Commit e1691496 authored by Adam Martinson's avatar Adam Martinson Committed by Alexandre Julliard

msxml3: Implement XSLPattern collection methods.

parent 42ccbc51
......@@ -522,7 +522,6 @@ HRESULT queryresult_create(xmlNodePtr node, LPCWSTR szQuery, IXMLDOMNodeList **o
{
xmlChar* tmp;
int len;
WARN("Attempting XSLPattern emulation (experimental).\n");
tmp = XSLPattern_to_XPath(ctxt, str);
len = (xmlStrlen(tmp)+1)*sizeof(xmlChar);
str = heap_realloc(str, len);
......
......@@ -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 */
......@@ -6733,46 +6697,37 @@ static void test_XSLPattern(void)
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();
......
......@@ -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
......@@ -54,6 +61,8 @@ static const xmlChar NameTest_mod_post[] = "']";
%left TOK_OpEq TOK_OpIEq TOK_OpNEq TOK_OpINEq
%left TOK_OpLt TOK_OpILt TOK_OpGt TOK_OpIGt TOK_OpLEq TOK_OpILEq TOK_OpGEq TOK_OpIGEq
%expect 14
%%
XSLPattern : Expr
......@@ -118,7 +127,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 +136,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 +171,9 @@ static const xmlChar NameTest_mod_post[] = "']";
;
/* [2.3] Node Tests */
NodeTest : NameTest
| FunctionCall
;
NameTest : '*'
{
TRACE("Got NameTest: \"*\"\n");
......@@ -285,23 +297,96 @@ static const xmlChar NameTest_mod_post[] = "']";
}
| TOK_Literal
| TOK_Number
| FunctionCall
;
/* [3.2] Function Calls */
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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment