@@ -69,29 +69,35 @@ public Object[][] getCountExp() {
69
69
{"count(//Customer)" , CUSTOMERS },
70
70
{"count(//@id)" , ID_ATTRIBUTES },
71
71
{"count(//Customer/@id)" , CUSTOMERS },
72
- {"count(//@*)" , ID_ATTRIBUTES + FOO_ID_ATTRIBUTES },
72
+ {"count(//@*)" ,
73
+ LANG_ATTRIBUTES + ID_ATTRIBUTES + FOO_ID_ATTRIBUTES },
73
74
{"count(//*)" ,
74
75
ROOT + CUSTOMERS + FOO_CUSTOMERS +
75
76
(CUSTOMERS + FOO_CUSTOMERS ) *
76
- CUSTOMER_ELEMENTS },
77
+ ( CUSTOMER_ELEMENTS + ADDRESS_ELEMENTS ) },
77
78
{"count(//*[@id])" , ID_ATTRIBUTES },
78
79
{"count(./*)" , ROOT },
80
+ {"count(.)" , ROOT },
79
81
{"count(//Customer[1]/following::*)" ,
80
82
CUSTOMERS - 1 + FOO_CUSTOMERS +
81
83
(CUSTOMERS - 1 + FOO_CUSTOMERS ) *
82
- CUSTOMER_ELEMENTS },
84
+ ( CUSTOMER_ELEMENTS + ADDRESS_ELEMENTS ) },
83
85
{"count(//Customer[1]/following-sibling::*)" ,
84
86
CUSTOMERS - 1 + FOO_CUSTOMERS },
85
87
{"count(//Customer[3]/preceding::*)" ,
86
- CUSTOMERS - 1 + (CUSTOMERS - 1 ) * CUSTOMER_ELEMENTS },
88
+ CUSTOMERS - 1 + (CUSTOMERS - 1 ) *
89
+ (CUSTOMER_ELEMENTS + ADDRESS_ELEMENTS )},
87
90
{"count(//Customer[3]/preceding-sibling::*)" , CUSTOMERS - 1 },
88
91
{"count(//Customer[1]/ancestor::*)" , ROOT },
89
92
{"count(//Customer[1]/ancestor-or-self::*)" , ROOT + 1 },
90
- {"count(//Customer[1]/descendant::*)" , CUSTOMER_ELEMENTS },
93
+ {"count(//Customer[1]/descendant::*)" ,
94
+ CUSTOMER_ELEMENTS + ADDRESS_ELEMENTS },
91
95
{"count(//Customer[1]/descendant-or-self::*)" ,
92
- CUSTOMER_ELEMENTS + 1 },
96
+ CUSTOMER_ELEMENTS + ADDRESS_ELEMENTS + 1 },
97
+ // node() returns all children of the context node including
98
+ // element nodes and text nodes.
93
99
{"count(//Customer/node())" ,
94
- ID_ATTRIBUTES + CUSTOMERS * CUSTOMER_ELEMENTS },
100
+ CUSTOMERS + CUSTOMERS * ( CUSTOMER_ELEMENTS * 2 ) },
95
101
};
96
102
}
97
103
@@ -104,6 +110,7 @@ public Object[][] getCountExp() {
104
110
public Object [][] getPositionExp () {
105
111
return new Object [][]{
106
112
{"//Customer[position()=1]" , "Customer_x1" },
113
+ {"//Customer[position()]" , "Customer_x1" },
107
114
{"//Customer[position()=last()]" , "Customer_x3" },
108
115
{"//Customer[position()>1 and position()<last()]" ,
109
116
"Customer_x2" },
@@ -125,18 +132,62 @@ public Object[][] getNameExp() {
125
132
{"local-name(//Customer/@id)" , "id" },
126
133
{"local-name(//foo:Customer/@foo:id)" , "id" },
127
134
{"local-name(//*[local-name()='Customer'])" , "Customer" },
135
+ {"local-name(//*[local-name(.)='Customer'])" , "Customer" },
128
136
{"namespace-uri(.)" , "" },
129
137
{"namespace-uri(//Customers)" , "" },
130
138
{"namespace-uri(//Customer)" , "" },
131
139
{"namespace-uri(//foo:Customer)" , "foo" },
132
140
{"namespace-uri(//@id)" , "" },
133
141
{"namespace-uri(//@foo:id)" , "foo" },
134
142
{"name(//*[namespace-uri()=\" foo\" ])" , "foo:Customer" },
143
+ {"name(//*[namespace-uri(.)=\" foo\" ])" , "foo:Customer" },
135
144
{"name(//Customer)" , "Customer" },
136
145
{"name(//foo:Customer)" , "foo:Customer" },
137
146
{"name(//Customer/@id)" , "id" },
138
147
{"name(//foo:Customer/@foo:id)" , "foo:id" },
139
148
{"name(//*[name()='foo:Customer'])" , "foo:Customer" },
149
+ {"name(//*[name(.)='foo:Customer'])" , "foo:Customer" },
150
+ };
151
+ }
152
+
153
+ /*
154
+ * DataProvider for testing XPathExpressionException being thrown on
155
+ * invalid node set function usage.
156
+ * Data columns:
157
+ * see parameters of the test "testExceptionOnEval"
158
+ */
159
+ @ DataProvider (name = "exceptionExpTestCases" )
160
+ public Object [][] getExceptionExp () {
161
+ return new Object [][]{
162
+ // Argument is required for these functions
163
+ {"//Customer[id()]" },
164
+ {"//Customer[id()='x1']" },
165
+ {"//Customer[count()]" },
166
+ {"//*[count()=3]" },
167
+
168
+ // No argument should be passed to these functions
169
+ {"//Customer[position(.)]" },
170
+ {"//*[position(//Customer[1])]" },
171
+ {"//Customer[last(.)]" },
172
+ {"//*[last(//Customer[1])]" },
173
+
174
+ // Node-set argument is required for these functions
175
+ {"count(1)" },
176
+ {"count(true())" },
177
+ {"count('')" },
178
+ {"count('abc')" },
179
+ {"local-name(1)" },
180
+ {"local-name(true())" },
181
+ {"local-name('')" },
182
+ {"local-name('abc')" },
183
+ {"name(1)" },
184
+ {"name(true())" },
185
+ {"name('')" },
186
+ {"name('abc')" },
187
+ {"namespace-uri(1)" },
188
+ {"namespace-uri(true())" },
189
+ {"namespace-uri('')" },
190
+ {"namespace-uri('abc')" },
140
191
};
141
192
}
142
193
@@ -219,4 +270,15 @@ void testNameFn(String exp, String expected) throws Exception {
219
270
Assert .assertEquals (s , expected );
220
271
Assert .assertEquals (s2 , s );
221
272
}
273
+
274
+ /**
275
+ * Verifies that XPathExpressionException is thrown on xpath evaluation.
276
+ *
277
+ * @param exp XPath expression
278
+ */
279
+ @ Test (dataProvider = "exceptionExpTestCases" )
280
+ void testExceptionOnEval (String exp ) {
281
+ Assert .assertThrows (XPathExpressionException .class , () -> testEval (doc ,
282
+ exp ));
283
+ }
222
284
}
0 commit comments