[PATCH 8/8] msxml3: Implement XSLPattern collection methods
Adam Martinson
amartinson at codeweavers.com
Thu Oct 28 20:22:22 CDT 2010
---
dlls/msxml3/tests/domdoc.c | 225 ++++++++++++++++++--------------------------
dlls/msxml3/xslpattern.y | 106 +++++++++++++++++++--
2 files changed, 185 insertions(+), 146 deletions(-)
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 5b35070..fe35494 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -6571,136 +6571,100 @@ static void test_XSLPattern(void)
list = NULL;
/* attribute() */
- todo_wine ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("attribute()"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- todo_wine ok(len == 0, "expected empty list\n");
- if (len)
- IXMLDOMNodeList_Release(list);
- }
+ ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("attribute()"), &list));
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len == 0, "expected empty list\n");
+ if (len)
+ IXMLDOMNodeList_Release(list);
- todo_wine ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("attribute('depth')"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- todo_wine ok(len == 0, "expected empty list\n");
- if (len)
- IXMLDOMNodeList_Release(list);
- }
+ ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("attribute('depth')"), &list));
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len == 0, "expected empty list\n");
+ if (len)
+ IXMLDOMNodeList_Release(list);
- todo_wine ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/attribute('depth')"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- todo_wine ok(len != 0, "expected filled list\n");
- if (len)
- todo_wine expect_list_and_release(list, "A'depth'.E3.D1");
- }
+ ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/attribute('depth')"), &list));
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "A'depth'.E3.D1");
- todo_wine ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/attribute()"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- todo_wine ok(len != 0, "expected filled list\n");
- if (len)
- todo_wine expect_list_and_release(list, "A'id'.E3.E3.D1 A'depth'.E3.E3.D1");
- }
+ ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/attribute()"), &list));
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "A'id'.E3.E3.D1 A'depth'.E3.E3.D1");
list = NULL;
ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x//attribute(id)"), &list), E_FAIL);
if (list)
IXMLDOMNodeList_Release(list);
- todo_wine ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x//attribute('id')"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- todo_wine ok(len != 0, "expected filled list\n");
- if (len)
- todo_wine expect_list_and_release(list, "A'id'.E3.E3.D1 A'id'.E4.E3.E3.D1 A'id'.E5.E3.E3.D1 A'id'.E6.E3.E3.D1");
- }
+ ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x//attribute('id')"), &list));
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "A'id'.E3.E3.D1 A'id'.E4.E3.E3.D1 A'id'.E5.E3.E3.D1 A'id'.E6.E3.E3.D1");
/* comment() */
ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("comment()"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- ok(len != 0, "expected filled list\n");
- if (len)
- expect_list_and_release(list, "C2.D1");
- }
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "C2.D1");
ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//comment()"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- ok(len != 0, "expected filled list\n");
- if (len)
- expect_list_and_release(list, "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1");
- }
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "C2.D1 C1.E3.D1 C2.E3.E3.D1 C2.E4.E3.D1");
/* element() */
- todo_wine ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("element()"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- todo_wine ok(len != 0, "expected filled list\n");
- if (len)
- todo_wine expect_list_and_release(list, "E3.D1");
- }
+ ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("element()"), &list));
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "E3.D1");
- todo_wine ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/y/element()"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- todo_wine ok(len != 0, "expected filled list\n");
- if (len)
- todo_wine expect_list_and_release(list, "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1");
- }
+ ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/y/element()"), &list));
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "E4.E4.E3.D1 E5.E4.E3.D1 E6.E4.E3.D1");
list = NULL;
ole_expect(IXMLDOMDocument2_selectNodes(doc, _bstr_("//element(a)"), &list), E_FAIL);
if (list)
IXMLDOMNodeList_Release(list);
- todo_wine ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//element('a')"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- todo_wine ok(len != 0, "expected filled list\n");
- if (len)
- todo_wine expect_list_and_release(list, "E4.E3.E3.D1 E4.E4.E3.D1");
- }
+ ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//element('a')"), &list));
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "E4.E3.E3.D1 E4.E4.E3.D1");
/* node() */
ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("node()"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- ok(len != 0, "expected filled list\n");
- if (len)
- expect_list_and_release(list, "P1.D1 C2.D1 E3.D1");
- }
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "P1.D1 C2.D1 E3.D1");
ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//x/node()"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- ok(len != 0, "expected filled list\n");
- if (len)
- expect_list_and_release(list, "P1.E3.E3.D1 C2.E3.E3.D1 T3.E3.E3.D1 E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1");
- }
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "P1.E3.E3.D1 C2.E3.E3.D1 T3.E3.E3.D1 E4.E3.E3.D1 E5.E3.E3.D1 E6.E3.E3.D1");
/* nodeType() */
/* XML_ELEMENT_NODE */
@@ -6730,49 +6694,40 @@ static void test_XSLPattern(void)
ole_check(IXMLDOMNodeList_get_length(list, &len));
ok(len != 0, "expected filled list\n");
if (len)
- expect_list_and_release(list, "T3.E3.E3.D1");
+ expect_list_and_release(list, "C2.E3.E3.D1");
/* pi() */
- todo_wine ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("pi()"), &list));
+ ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("pi()"), &list));
if (list)
{
len = 0;
ole_check(IXMLDOMNodeList_get_length(list, &len));
- todo_wine ok(len != 0, "expected filled list\n");
+ ok(len != 0, "expected filled list\n");
if (len)
- todo_wine expect_list_and_release(list, "P1.D1");
+ expect_list_and_release(list, "P1.D1");
}
- todo_wine ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//y/pi()"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- todo_wine ok(len != 0, "expected filled list\n");
- if (len)
- todo_wine expect_list_and_release(list, "P1.E4.E3.D1");
- }
+ ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//y/pi()"), &list));
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "P1.E4.E3.D1");
/* textnode() */
- todo_wine ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/textnode()"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- todo_wine ok(len != 0, "expected filled list\n");
- if (len)
- todo_wine expect_list_and_release(list, "T2.E3.D1");
- }
+ ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/textnode()"), &list));
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "T2.E3.D1");
- todo_wine ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/element()/textnode()"), &list));
- if (list)
- {
- len = 0;
- ole_check(IXMLDOMNodeList_get_length(list, &len));
- todo_wine ok(len != 0, "expected filled list\n");
- if (len)
- todo_wine expect_list_and_release(list, "T3.E3.E3.D1 T3.E4.E3.D1");
- }
+ ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("root/element()/textnode()"), &list));
+ len = 0;
+ ole_check(IXMLDOMNodeList_get_length(list, &len));
+ ok(len != 0, "expected filled list\n");
+ if (len)
+ expect_list_and_release(list, "T3.E3.E3.D1 T3.E4.E3.D1");
IXMLDOMDocument2_Release(doc);
free_bstrs();
diff --git a/dlls/msxml3/xslpattern.y b/dlls/msxml3/xslpattern.y
index e5d4449..958956e 100644
--- a/dlls/msxml3/xslpattern.y
+++ b/dlls/msxml3/xslpattern.y
@@ -34,6 +34,13 @@ static const xmlChar NameTest_mod_post[] = "']";
#define U(str) BAD_CAST str
+static inline BOOL is_literal(xmlChar const* tok)
+{
+ return (tok && tok[0] && tok[1] &&
+ tok[0]== tok[xmlStrlen(tok)-1] &&
+ (tok[0] == '\'' || tok[0] == '"'));
+}
+
%}
%token TOK_Parent TOK_Self TOK_DblFSlash TOK_FSlash TOK_Axis TOK_Colon
@@ -118,7 +125,7 @@ static const xmlChar NameTest_mod_post[] = "']";
| AbbreviatedRelativeLocationPath
;
/* [2.1] Location Steps */
- Step : AxisSpecifier NameTest Predicates
+ Step : AxisSpecifier NodeTest Predicates
{
TRACE("Got Step: \"%s%s%s\"\n", $1, $2, $3);
$$=$1;
@@ -127,21 +134,21 @@ static const xmlChar NameTest_mod_post[] = "']";
$$=xmlStrcat($$,$3);
xmlFree($3);
}
- | NameTest Predicates
+ | NodeTest Predicates
{
TRACE("Got Step: \"%s%s\"\n", $1, $2);
$$=$1;
$$=xmlStrcat($$,$2);
xmlFree($2);
}
- | AxisSpecifier NameTest
+ | AxisSpecifier NodeTest
{
TRACE("Got Step: \"%s%s\"\n", $1, $2);
$$=$1;
$$=xmlStrcat($$,$2);
xmlFree($2);
}
- | NameTest
+ | NodeTest
| Attribute
| AbbreviatedStep
;
@@ -162,6 +169,9 @@ static const xmlChar NameTest_mod_post[] = "']";
;
/* [2.3] Node Tests */
+ NodeTest : NameTest
+ | FunctionCall
+ ;
NameTest : '*'
{
TRACE("Got NameTest: \"*\"\n");
@@ -291,17 +301,91 @@ static const xmlChar NameTest_mod_post[] = "']";
FunctionCall : QName '(' Arguments ')'
{
TRACE("Got FunctionCall: \"%s(%s)\"\n", $1, $3);
- $$=$1;
- $$=xmlStrcat($$,U("("));
- $$=xmlStrcat($$,$3);
- xmlFree($3);
- $$=xmlStrcat($$,U(")"));
+ if (xmlStrEqual($1,U("ancestor")))
+ {
+ $$=$1;
+ $$=xmlStrcat($$,U("::"));
+ $$=xmlStrcat($$,$3);
+ xmlFree($3);
+ }
+ else if (xmlStrEqual($1,U("attribute")))
+ {
+ if (is_literal($3))
+ {
+ $$=xmlStrdup(U("@*[name()="));
+ xmlFree($1);
+ $$=xmlStrcat($$,$3);
+ xmlFree($3);
+ $$=xmlStrcat($$,U("]"));
+ }
+ else
+ {
+ /* XML_XPATH_INVALID_TYPE */
+ $$=xmlStrdup(U("error(1211, 'Error: attribute("));
+ xmlFree($1);
+ $$=xmlStrcat($$,$3);
+ xmlFree($3);
+ $$=xmlStrcat($$,U("): invalid argument"));
+ }
+ }
+ else if (xmlStrEqual($1,U("element")))
+ {
+ if (is_literal($3))
+ {
+ $$=xmlStrdup(U("node()[nodeType()=1][name()="));
+ xmlFree($1);
+ $$=xmlStrcat($$,$3);
+ xmlFree($3);
+ $$=xmlStrcat($$,U("]"));
+ }
+ else
+ {
+ /* XML_XPATH_INVALID_TYPE */
+ $$=xmlStrdup(U("error(1211, 'Error: element("));
+ xmlFree($1);
+ $$=xmlStrcat($$,$3);
+ xmlFree($3);
+ $$=xmlStrcat($$,U("): invalid argument"));
+ }
+ }
+ else
+ {
+ $$=$1;
+ $$=xmlStrcat($$,U("("));
+ $$=xmlStrcat($$,$3);
+ xmlFree($3);
+ $$=xmlStrcat($$,U(")"));
+ }
}
| QName '(' ')'
{
TRACE("Got FunctionCall: \"%s()\"\n", $1);
- $$=$1;
- $$=xmlStrcat($$,U("()"));
+ /* comment() & node() work the same in XPath */
+ if (xmlStrEqual($1,U("attribute")))
+ {
+ $$=xmlStrdup(U("@*"));
+ xmlFree($1);
+ }
+ else if (xmlStrEqual($1,U("element")))
+ {
+ $$=xmlStrdup(U("node()[nodeType()=1]"));
+ xmlFree($1);
+ }
+ else if (xmlStrEqual($1,U("pi")))
+ {
+ $$=xmlStrdup(U("processing-instruction()"));
+ xmlFree($1);
+ }
+ else if (xmlStrEqual($1,U("textnode")))
+ {
+ $$=xmlStrdup(U("text()"));
+ xmlFree($1);
+ }
+ else
+ {
+ $$=$1;
+ $$=xmlStrcat($$,U("()"));
+ }
}
;
Arguments : Argument ',' Arguments
--
1.7.2.3
--------------030403010502000903070902--
More information about the wine-patches
mailing list