1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.xml;
17
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertNotNull;
20 import static org.junit.Assert.assertNull;
21
22 import java.io.StringReader;
23
24 import javax.xml.xpath.XPath;
25 import javax.xml.xpath.XPathConstants;
26 import javax.xml.xpath.XPathExpressionException;
27 import javax.xml.xpath.XPathFactory;
28
29 import org.junit.Test;
30 import org.kuali.rice.test.BaseRiceTestCase;
31 import org.w3c.dom.Node;
32 import org.w3c.dom.NodeList;
33 import org.xml.sax.InputSource;
34
35
36 public class XPathTest extends BaseRiceTestCase {
37
38 private static final String XSTREAM_SAFE_PREFIX = "wf:xstreamsafe('";
39 private static final String XSTREAM_SAFE_SUFFIX = "')";
40 public static final String XSTREAM_MATCH_ANYWHERE_PREFIX = "//";
41 public static final String XSTREAM_MATCH_RELATIVE_PREFIX = "./";
42
43 private static final String TEST_DOC = "<root name=\"root\">\n" +
44 " <child name=\"child1\">\n" +
45 " <child_1 name=\"child1_1\">\n" +
46 " <closedSimple/>\n" +
47 " <emptySimple></emptySimple>\n" +
48 " <textSimple>some text 1</textSimple>\n" +
49 " </child_1>\n" +
50 " </child>\n" +
51 " <child name=\"child2\">\n" +
52 " <child_2 name=\"child2_1\">\n" +
53 " <closedSimple/>\n" +
54 " <emptySimple></emptySimple>\n" +
55 " <textSimple>some text 2</textSimple>\n" +
56 " </child_2>\n" +
57 " </child>\n" +
58 "</root>";
59
60 private static final String TEST_ATTRIBUTE_DOC = "<root name=\"root\">\n" +
61 " <field name=\"one\" type=\"ALL\"/>\n" +
62 " <field name=\"two\" type=\"REPORT\"/>\n" +
63 " <field name=\"three\"/>\n" +
64 "</root>";
65
66 private static final XPath XPATH = XPathFactory.newInstance().newXPath();
67
68 private static final InputSource getTestInputSource() {
69 return new InputSource(new StringReader(TEST_DOC));
70 }
71
72 @Test public void testAttributeAbsence() throws XPathExpressionException {
73 NodeList nodes = (NodeList) XPATH.evaluate("/root/child[not(@nonExistentAttribute)]", getTestInputSource(), XPathConstants.NODESET);
74 assertEquals(2, nodes.getLength());
75 assertEquals("child1", nodes.item(0).getAttributes().getNamedItem("name").getNodeValue());
76 assertEquals("child2", nodes.item(1).getAttributes().getNamedItem("name").getNodeValue());
77
78
79 nodes = (NodeList) XPATH.evaluate("/root/*[local-name(.) = 'child' or (@nonExistentAttribute)]", getTestInputSource(), XPathConstants.NODESET);
80 assertEquals(2, nodes.getLength());
81 assertEquals("child1", nodes.item(0).getAttributes().getNamedItem("name").getNodeValue());
82 assertEquals("child2", nodes.item(1).getAttributes().getNamedItem("name").getNodeValue());
83
84 nodes = (NodeList) XPATH.evaluate("/root/child[not(@name)]", getTestInputSource(), XPathConstants.NODE);
85 assertNull(nodes);
86
87
88 nodes = (NodeList) XPATH.evaluate("/root/field[@type='ALL' or not(@type)]", new InputSource(new StringReader(TEST_ATTRIBUTE_DOC)), XPathConstants.NODESET);
89 assertEquals(2, nodes.getLength());
90 assertEquals("one", nodes.item(0).getAttributes().getNamedItem("name").getNodeValue());
91 assertEquals("three", nodes.item(1).getAttributes().getNamedItem("name").getNodeValue());
92 }
93
94 @Test public void testSelectJustChilds() throws XPathExpressionException {
95 NodeList nodes = (NodeList) XPATH.evaluate("/root/child", getTestInputSource(), XPathConstants.NODESET);
96 assertEquals(2, nodes.getLength());
97 assertEquals("child1", nodes.item(0).getAttributes().getNamedItem("name").getNodeValue());
98 assertEquals("child2", nodes.item(1).getAttributes().getNamedItem("name").getNodeValue());
99 }
100
101 @Test public void testSelectAbsoluteChild() throws XPathExpressionException {
102 Node node = (Node) XPATH.evaluate("/root/child", getTestInputSource(), XPathConstants.NODE);
103 assertEquals("child1", node.getAttributes().getNamedItem("name").getNodeValue());
104 }
105
106 @Test public void testSelectAnyChild() throws XPathExpressionException {
107 Node anyNode = (Node) XPATH.evaluate("//child", getTestInputSource(), XPathConstants.NODE);
108 assertEquals("child1", anyNode.getAttributes().getNamedItem("name").getNodeValue());
109 }
110
111 @Test public void testNonexistent() throws XPathExpressionException {
112 final String expr = "//child/child_1/nonExistent";
113 Node nonexistent = (Node) XPATH.evaluate(expr, getTestInputSource(), XPathConstants.NODE);
114 assertNull(nonexistent);
115 String valueOfNonexistentElement = (String) XPATH.evaluate(expr, getTestInputSource(), XPathConstants.STRING);
116
117 assertEquals("", valueOfNonexistentElement);
118 }
119
120 @Test public void testClosedSimple() throws XPathExpressionException {
121 final String expr = "//child/child_1/closedSimple";
122 Node closedSimple = (Node) XPATH.evaluate(expr, getTestInputSource(), XPathConstants.NODE);
123 assertNotNull(closedSimple);
124 assertNull(closedSimple.getFirstChild());
125 String valueOfClosedTag = (String) XPATH.evaluate(expr, getTestInputSource(), XPathConstants.STRING);
126
127 assertEquals("", valueOfClosedTag);
128 }
129
130 @Test public void testEmptySimple() throws XPathExpressionException {
131 final String expr = "//child/child_1/emptySimple";
132 Node emptySimple = (Node) XPATH.evaluate(expr, getTestInputSource(), XPathConstants.NODE);
133 assertNotNull(emptySimple);
134 assertNull(emptySimple.getFirstChild());
135 String valueOfEmptyTag = (String) XPATH.evaluate(expr, getTestInputSource(), XPathConstants.STRING);
136
137 assertEquals("", valueOfEmptyTag);
138 }
139
140 @Test public void testText() throws XPathExpressionException {
141 final String expr = "//child/child_2[@name='child2_1']/textSimple";
142 final String expected = "some text 2";
143 Node textSimple = (Node) XPATH.evaluate(expr, getTestInputSource(), XPathConstants.NODE);
144 assertNotNull(textSimple);
145 assertNotNull(textSimple.getFirstChild());
146 String valueOfTextTag = (String) XPATH.evaluate(expr, getTestInputSource(), XPathConstants.STRING);
147
148 assertEquals(expected, valueOfTextTag);
149 }
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214 private String constructXpathExpression(String valueForTrue, String valueForFalse, String booleanXPathExpression) {
215 String[] xpathElementsToInsert = new String[3];
216 xpathElementsToInsert[0] = "concat( substring('" + valueForTrue + "', number(not(";
217 xpathElementsToInsert[1] = "))*string-length('" + valueForTrue + "')+1), substring('" + valueForFalse + "', number(";
218 xpathElementsToInsert[2] = ")*string-length('" + valueForFalse + "')+1))";
219
220 StringBuffer returnableString = new StringBuffer();
221 for (int i = 0; i < xpathElementsToInsert.length; i++) {
222 String newXpathElement = xpathElementsToInsert[i];
223 returnableString.append(newXpathElement);
224
225
226
227
228
229
230 if (((i + 1) != xpathElementsToInsert.length) || (xpathElementsToInsert.length == 1)) {
231 returnableString.append(booleanXPathExpression);
232 }
233 }
234 return returnableString.toString();
235
236 }
237 }