msxml3: Implement XSLPattern collection methods.
This commit is contained in:
parent
42ccbc5132
commit
e16914963e
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue