mirror of
https://gitlab.gnome.org/GNOME/libxslt
synced 2025-11-04 00:53:12 +03:00
Big fixes of pattern compilations
The problem is that "@node()", "attribute::node()", "child::node()" and "node()" are all handled in different code paths and only the latter works. Then, I noticed that the handling of match="child::name" is wrong. It matches the parents of <name> elements although it should be treated exactly like match="name". So the whole XSLT_OP_CHILD stuff is unneeded. I also found that xsltScanName behaves a bit strange with regard to ':' characters. It doesn't parse an XML Name like the documentation says. It's better to use xsltScanNCName instead. Another minor issue is that the parser currently allows invalid expressions like match="element*" because of lines 1745-1747 in pattern.c in trunk. * libxslt/pattern.c: fix all those problems * tests/REC/Makefile.am tests/REC/test-5.2-19* tests/REC/test-5.2-20* tests/REC/test-5.2-21*: add test cases to the regression suite
This commit is contained in:
committed by
Daniel Veillard
parent
d65daeaf65
commit
3d435b25cf
@@ -46,7 +46,6 @@ typedef enum {
|
|||||||
XSLT_OP_END=0,
|
XSLT_OP_END=0,
|
||||||
XSLT_OP_ROOT,
|
XSLT_OP_ROOT,
|
||||||
XSLT_OP_ELEM,
|
XSLT_OP_ELEM,
|
||||||
XSLT_OP_CHILD,
|
|
||||||
XSLT_OP_ATTR,
|
XSLT_OP_ATTR,
|
||||||
XSLT_OP_PARENT,
|
XSLT_OP_PARENT,
|
||||||
XSLT_OP_ANCESTOR,
|
XSLT_OP_ANCESTOR,
|
||||||
@@ -61,6 +60,11 @@ typedef enum {
|
|||||||
XSLT_OP_PREDICATE
|
XSLT_OP_PREDICATE
|
||||||
} xsltOp;
|
} xsltOp;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
AXIS_CHILD=1,
|
||||||
|
AXIS_ATTRIBUTE
|
||||||
|
} xsltAxis;
|
||||||
|
|
||||||
typedef struct _xsltStepState xsltStepState;
|
typedef struct _xsltStepState xsltStepState;
|
||||||
typedef xsltStepState *xsltStepStatePtr;
|
typedef xsltStepState *xsltStepStatePtr;
|
||||||
struct _xsltStepState {
|
struct _xsltStepState {
|
||||||
@@ -697,32 +701,6 @@ restart:
|
|||||||
goto rollback;
|
goto rollback;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
case XSLT_OP_CHILD: {
|
|
||||||
xmlNodePtr lst;
|
|
||||||
|
|
||||||
if ((node->type != XML_ELEMENT_NODE) &&
|
|
||||||
(node->type != XML_DOCUMENT_NODE) &&
|
|
||||||
#ifdef LIBXML_DOCB_ENABLED
|
|
||||||
(node->type != XML_DOCB_DOCUMENT_NODE) &&
|
|
||||||
#endif
|
|
||||||
(node->type != XML_HTML_DOCUMENT_NODE))
|
|
||||||
goto rollback;
|
|
||||||
|
|
||||||
lst = node->children;
|
|
||||||
|
|
||||||
if (step->value != NULL) {
|
|
||||||
while (lst != NULL) {
|
|
||||||
if ((lst->type == XML_ELEMENT_NODE) &&
|
|
||||||
(step->value[0] == lst->name[0]) &&
|
|
||||||
(xmlStrEqual(step->value, lst->name)))
|
|
||||||
break;
|
|
||||||
lst = lst->next;
|
|
||||||
}
|
|
||||||
if (lst != NULL)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
goto rollback;
|
|
||||||
}
|
|
||||||
case XSLT_OP_ATTR:
|
case XSLT_OP_ATTR:
|
||||||
if (node->type != XML_ATTRIBUTE_NODE)
|
if (node->type != XML_ATTRIBUTE_NODE)
|
||||||
goto rollback;
|
goto rollback;
|
||||||
@@ -1329,46 +1307,6 @@ xsltScanLiteral(xsltParserContextPtr ctxt) {
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* xsltScanName:
|
|
||||||
* @ctxt: the XPath Parser context
|
|
||||||
*
|
|
||||||
* [4] NameChar ::= Letter | Digit | '.' | '-' | '_' |
|
|
||||||
* CombiningChar | Extender
|
|
||||||
*
|
|
||||||
* [5] Name ::= (Letter | '_' | ':') (NameChar)*
|
|
||||||
*
|
|
||||||
* [6] Names ::= Name (S Name)*
|
|
||||||
*
|
|
||||||
* Returns the Name parsed or NULL
|
|
||||||
*/
|
|
||||||
|
|
||||||
static xmlChar *
|
|
||||||
xsltScanName(xsltParserContextPtr ctxt) {
|
|
||||||
const xmlChar *q, *cur;
|
|
||||||
xmlChar *ret = NULL;
|
|
||||||
int val, len;
|
|
||||||
|
|
||||||
SKIP_BLANKS;
|
|
||||||
|
|
||||||
cur = q = CUR_PTR;
|
|
||||||
val = xmlStringCurrentChar(NULL, cur, &len);
|
|
||||||
if (!IS_LETTER(val) && (val != '_') && (val != ':'))
|
|
||||||
return(NULL);
|
|
||||||
|
|
||||||
while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
|
|
||||||
(val == '.') || (val == '-') ||
|
|
||||||
(val == '_') ||
|
|
||||||
(IS_COMBINING(val)) ||
|
|
||||||
(IS_EXTENDER(val))) {
|
|
||||||
cur += len;
|
|
||||||
val = xmlStringCurrentChar(NULL, cur, &len);
|
|
||||||
}
|
|
||||||
ret = xmlStrndup(q, cur - q);
|
|
||||||
CUR_PTR = cur;
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xsltScanNCName:
|
* xsltScanNCName:
|
||||||
* @ctxt: the XPath Parser context
|
* @ctxt: the XPath Parser context
|
||||||
@@ -1404,30 +1342,6 @@ xsltScanNCName(xsltParserContextPtr ctxt) {
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* xsltScanQName:
|
|
||||||
* @ctxt: the XPath Parser context
|
|
||||||
* @prefix: the place to store the prefix
|
|
||||||
*
|
|
||||||
* Parse a qualified name
|
|
||||||
*
|
|
||||||
* Returns the Name parsed or NULL
|
|
||||||
*/
|
|
||||||
|
|
||||||
static xmlChar *
|
|
||||||
xsltScanQName(xsltParserContextPtr ctxt, xmlChar **prefix) {
|
|
||||||
xmlChar *ret = NULL;
|
|
||||||
|
|
||||||
*prefix = NULL;
|
|
||||||
ret = xsltScanNCName(ctxt);
|
|
||||||
if (ret && CUR == ':') {
|
|
||||||
*prefix = ret;
|
|
||||||
NEXT;
|
|
||||||
ret = xsltScanNCName(ctxt);
|
|
||||||
}
|
|
||||||
return(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* xsltCompileIdKeyPattern:
|
* xsltCompileIdKeyPattern:
|
||||||
* @ctxt: the compilation context
|
* @ctxt: the compilation context
|
||||||
@@ -1447,7 +1361,7 @@ xsltScanQName(xsltParserContextPtr ctxt, xmlChar **prefix) {
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name,
|
xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name,
|
||||||
int aid, int novar) {
|
int aid, int novar, xsltAxis axis) {
|
||||||
xmlChar *lit = NULL;
|
xmlChar *lit = NULL;
|
||||||
xmlChar *lit2 = NULL;
|
xmlChar *lit2 = NULL;
|
||||||
|
|
||||||
@@ -1458,6 +1372,12 @@ xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((aid) && (xmlStrEqual(name, (const xmlChar *)"id"))) {
|
if ((aid) && (xmlStrEqual(name, (const xmlChar *)"id"))) {
|
||||||
|
if (axis != 0) {
|
||||||
|
xsltTransformError(NULL, NULL, NULL,
|
||||||
|
"xsltCompileIdKeyPattern : NodeTest expected\n");
|
||||||
|
ctxt->error = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
NEXT;
|
NEXT;
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
lit = xsltScanLiteral(ctxt);
|
lit = xsltScanLiteral(ctxt);
|
||||||
@@ -1473,6 +1393,12 @@ xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name,
|
|||||||
NEXT;
|
NEXT;
|
||||||
PUSH(XSLT_OP_ID, lit, NULL, novar);
|
PUSH(XSLT_OP_ID, lit, NULL, novar);
|
||||||
} else if ((aid) && (xmlStrEqual(name, (const xmlChar *)"key"))) {
|
} else if ((aid) && (xmlStrEqual(name, (const xmlChar *)"key"))) {
|
||||||
|
if (axis != 0) {
|
||||||
|
xsltTransformError(NULL, NULL, NULL,
|
||||||
|
"xsltCompileIdKeyPattern : NodeTest expected\n");
|
||||||
|
ctxt->error = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
NEXT;
|
NEXT;
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
lit = xsltScanLiteral(ctxt);
|
lit = xsltScanLiteral(ctxt);
|
||||||
@@ -1549,7 +1475,12 @@ xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
NEXT;
|
NEXT;
|
||||||
PUSH(XSLT_OP_NODE, NULL, NULL, novar);
|
if (axis == AXIS_ATTRIBUTE) {
|
||||||
|
PUSH(XSLT_OP_ATTR, NULL, NULL, novar);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PUSH(XSLT_OP_NODE, NULL, NULL, novar);
|
||||||
|
}
|
||||||
} else if (aid) {
|
} else if (aid) {
|
||||||
xsltTransformError(NULL, NULL, NULL,
|
xsltTransformError(NULL, NULL, NULL,
|
||||||
"xsltCompileIdKeyPattern : expecting 'key' or 'id' or node type\n");
|
"xsltCompileIdKeyPattern : expecting 'key' or 'id' or node type\n");
|
||||||
@@ -1594,51 +1525,25 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) {
|
|||||||
const xmlChar *URI = NULL;
|
const xmlChar *URI = NULL;
|
||||||
xmlChar *URL = NULL;
|
xmlChar *URL = NULL;
|
||||||
int level;
|
int level;
|
||||||
|
xsltAxis axis = 0;
|
||||||
|
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if ((token == NULL) && (CUR == '@')) {
|
if ((token == NULL) && (CUR == '@')) {
|
||||||
xmlChar *prefix = NULL;
|
|
||||||
|
|
||||||
NEXT;
|
NEXT;
|
||||||
if (CUR == '*') {
|
axis = AXIS_ATTRIBUTE;
|
||||||
NEXT;
|
|
||||||
PUSH(XSLT_OP_ATTR, NULL, NULL, novar);
|
|
||||||
goto parse_predicate;
|
|
||||||
}
|
|
||||||
token = xsltScanQName(ctxt, &prefix);
|
|
||||||
if (prefix != NULL) {
|
|
||||||
xmlNsPtr ns;
|
|
||||||
|
|
||||||
ns = xmlSearchNs(ctxt->doc, ctxt->elem, prefix);
|
|
||||||
if (ns == NULL) {
|
|
||||||
xsltTransformError(NULL, NULL, NULL,
|
|
||||||
"xsltCompileStepPattern : no namespace bound to prefix %s\n",
|
|
||||||
prefix);
|
|
||||||
} else {
|
|
||||||
URL = xmlStrdup(ns->href);
|
|
||||||
}
|
|
||||||
xmlFree(prefix);
|
|
||||||
}
|
|
||||||
if (token == NULL) {
|
|
||||||
if (CUR == '*') {
|
|
||||||
NEXT;
|
|
||||||
PUSH(XSLT_OP_ATTR, NULL, URL, novar);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
xsltTransformError(NULL, NULL, NULL,
|
|
||||||
"xsltCompileStepPattern : Name expected\n");
|
|
||||||
ctxt->error = 1;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
PUSH(XSLT_OP_ATTR, token, URL, novar);
|
|
||||||
goto parse_predicate;
|
|
||||||
}
|
}
|
||||||
|
parse_node_test:
|
||||||
if (token == NULL)
|
if (token == NULL)
|
||||||
token = xsltScanName(ctxt);
|
token = xsltScanNCName(ctxt);
|
||||||
if (token == NULL) {
|
if (token == NULL) {
|
||||||
if (CUR == '*') {
|
if (CUR == '*') {
|
||||||
NEXT;
|
NEXT;
|
||||||
PUSH(XSLT_OP_ALL, token, NULL, novar);
|
if (axis == AXIS_ATTRIBUTE) {
|
||||||
|
PUSH(XSLT_OP_ATTR, NULL, NULL, novar);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PUSH(XSLT_OP_ALL, NULL, NULL, novar);
|
||||||
|
}
|
||||||
goto parse_predicate;
|
goto parse_predicate;
|
||||||
} else {
|
} else {
|
||||||
xsltTransformError(NULL, NULL, NULL,
|
xsltTransformError(NULL, NULL, NULL,
|
||||||
@@ -1651,7 +1556,7 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) {
|
|||||||
|
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if (CUR == '(') {
|
if (CUR == '(') {
|
||||||
xsltCompileIdKeyPattern(ctxt, token, 0, novar);
|
xsltCompileIdKeyPattern(ctxt, token, 0, novar, axis);
|
||||||
if (ctxt->error)
|
if (ctxt->error)
|
||||||
goto error;
|
goto error;
|
||||||
} else if (CUR == ':') {
|
} else if (CUR == ':') {
|
||||||
@@ -1663,7 +1568,7 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) {
|
|||||||
/*
|
/*
|
||||||
* This is a namespace match
|
* This is a namespace match
|
||||||
*/
|
*/
|
||||||
token = xsltScanName(ctxt);
|
token = xsltScanNCName(ctxt);
|
||||||
ns = xmlSearchNs(ctxt->doc, ctxt->elem, prefix);
|
ns = xmlSearchNs(ctxt->doc, ctxt->elem, prefix);
|
||||||
if (ns == NULL) {
|
if (ns == NULL) {
|
||||||
xsltTransformError(NULL, NULL, NULL,
|
xsltTransformError(NULL, NULL, NULL,
|
||||||
@@ -1679,7 +1584,12 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) {
|
|||||||
if (token == NULL) {
|
if (token == NULL) {
|
||||||
if (CUR == '*') {
|
if (CUR == '*') {
|
||||||
NEXT;
|
NEXT;
|
||||||
PUSH(XSLT_OP_NS, URL, NULL, novar);
|
if (axis == AXIS_ATTRIBUTE) {
|
||||||
|
PUSH(XSLT_OP_ATTR, NULL, URL, novar);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PUSH(XSLT_OP_NS, URL, NULL, novar);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
xsltTransformError(NULL, NULL, NULL,
|
xsltTransformError(NULL, NULL, NULL,
|
||||||
"xsltCompileStepPattern : Name expected\n");
|
"xsltCompileStepPattern : Name expected\n");
|
||||||
@@ -1687,54 +1597,25 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) {
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PUSH(XSLT_OP_ELEM, token, URL, novar);
|
if (axis == AXIS_ATTRIBUTE) {
|
||||||
|
PUSH(XSLT_OP_ATTR, token, URL, novar);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PUSH(XSLT_OP_ELEM, token, URL, novar);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (axis != 0) {
|
||||||
|
xsltTransformError(NULL, NULL, NULL,
|
||||||
|
"xsltCompileStepPattern : NodeTest expected\n");
|
||||||
|
ctxt->error = 1;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
NEXT;
|
NEXT;
|
||||||
if (xmlStrEqual(token, (const xmlChar *) "child")) {
|
if (xmlStrEqual(token, (const xmlChar *) "child")) {
|
||||||
xmlFree(token);
|
axis = AXIS_CHILD;
|
||||||
token = xsltScanName(ctxt);
|
|
||||||
if (token == NULL) {
|
|
||||||
if (CUR == '*') {
|
|
||||||
NEXT;
|
|
||||||
PUSH(XSLT_OP_ALL, token, NULL, novar);
|
|
||||||
goto parse_predicate;
|
|
||||||
} else {
|
|
||||||
xsltTransformError(NULL, NULL, NULL,
|
|
||||||
"xsltCompileStepPattern : QName expected\n");
|
|
||||||
ctxt->error = 1;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
URI = xsltGetQNameURI(ctxt->elem, &token);
|
|
||||||
if (token == NULL) {
|
|
||||||
ctxt->error = 1;
|
|
||||||
goto error;
|
|
||||||
} else {
|
|
||||||
name = xmlStrdup(token);
|
|
||||||
if (URI != NULL)
|
|
||||||
URL = xmlStrdup(URI);
|
|
||||||
}
|
|
||||||
PUSH(XSLT_OP_CHILD, name, URL, novar);
|
|
||||||
} else if (xmlStrEqual(token, (const xmlChar *) "attribute")) {
|
} else if (xmlStrEqual(token, (const xmlChar *) "attribute")) {
|
||||||
xmlFree(token);
|
axis = AXIS_ATTRIBUTE;
|
||||||
token = xsltScanName(ctxt);
|
|
||||||
if (token == NULL) {
|
|
||||||
xsltTransformError(NULL, NULL, NULL,
|
|
||||||
"xsltCompileStepPattern : QName expected\n");
|
|
||||||
ctxt->error = 1;
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
URI = xsltGetQNameURI(ctxt->elem, &token);
|
|
||||||
if (token == NULL) {
|
|
||||||
ctxt->error = 1;
|
|
||||||
goto error;
|
|
||||||
} else {
|
|
||||||
name = xmlStrdup(token);
|
|
||||||
if (URI != NULL)
|
|
||||||
URL = xmlStrdup(URI);
|
|
||||||
}
|
|
||||||
PUSH(XSLT_OP_ATTR, name, URL, novar);
|
|
||||||
} else {
|
} else {
|
||||||
xsltTransformError(NULL, NULL, NULL,
|
xsltTransformError(NULL, NULL, NULL,
|
||||||
"xsltCompileStepPattern : 'child' or 'attribute' expected\n");
|
"xsltCompileStepPattern : 'child' or 'attribute' expected\n");
|
||||||
@@ -1742,10 +1623,10 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) {
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
xmlFree(token);
|
xmlFree(token);
|
||||||
|
SKIP_BLANKS;
|
||||||
|
token = xsltScanNCName(ctxt);
|
||||||
|
goto parse_node_test;
|
||||||
}
|
}
|
||||||
} else if (CUR == '*') {
|
|
||||||
NEXT;
|
|
||||||
PUSH(XSLT_OP_ALL, token, NULL, novar);
|
|
||||||
} else {
|
} else {
|
||||||
URI = xsltGetQNameURI(ctxt->elem, &token);
|
URI = xsltGetQNameURI(ctxt->elem, &token);
|
||||||
if (token == NULL) {
|
if (token == NULL) {
|
||||||
@@ -1754,7 +1635,12 @@ xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) {
|
|||||||
}
|
}
|
||||||
if (URI != NULL)
|
if (URI != NULL)
|
||||||
URL = xmlStrdup(URI);
|
URL = xmlStrdup(URI);
|
||||||
PUSH(XSLT_OP_ELEM, token, URL, novar);
|
if (axis == AXIS_ATTRIBUTE) {
|
||||||
|
PUSH(XSLT_OP_ATTR, token, URL, novar);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PUSH(XSLT_OP_ELEM, token, URL, novar);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
parse_predicate:
|
parse_predicate:
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
@@ -1891,7 +1777,7 @@ xsltCompileLocationPathPattern(xsltParserContextPtr ctxt, int novar) {
|
|||||||
xsltCompileRelativePathPattern(ctxt, NULL, novar);
|
xsltCompileRelativePathPattern(ctxt, NULL, novar);
|
||||||
} else {
|
} else {
|
||||||
xmlChar *name;
|
xmlChar *name;
|
||||||
name = xsltScanName(ctxt);
|
name = xsltScanNCName(ctxt);
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
xsltTransformError(NULL, NULL, NULL,
|
xsltTransformError(NULL, NULL, NULL,
|
||||||
"xsltCompileLocationPathPattern : Name expected\n");
|
"xsltCompileLocationPathPattern : Name expected\n");
|
||||||
@@ -1900,7 +1786,7 @@ xsltCompileLocationPathPattern(xsltParserContextPtr ctxt, int novar) {
|
|||||||
}
|
}
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
if ((CUR == '(') && !xmlXPathIsNodeType(name)) {
|
if ((CUR == '(') && !xmlXPathIsNodeType(name)) {
|
||||||
xsltCompileIdKeyPattern(ctxt, name, 1, novar);
|
xsltCompileIdKeyPattern(ctxt, name, 1, novar, 0);
|
||||||
if ((CUR == '/') && (NXT(1) == '/')) {
|
if ((CUR == '/') && (NXT(1) == '/')) {
|
||||||
PUSH(XSLT_OP_ANCESTOR, NULL, NULL, novar);
|
PUSH(XSLT_OP_ANCESTOR, NULL, NULL, novar);
|
||||||
NEXT;
|
NEXT;
|
||||||
@@ -2178,7 +2064,6 @@ xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur,
|
|||||||
else
|
else
|
||||||
top = &(style->attrMatch);
|
top = &(style->attrMatch);
|
||||||
break;
|
break;
|
||||||
case XSLT_OP_CHILD:
|
|
||||||
case XSLT_OP_PARENT:
|
case XSLT_OP_PARENT:
|
||||||
case XSLT_OP_ANCESTOR:
|
case XSLT_OP_ANCESTOR:
|
||||||
top = &(style->elemMatch);
|
top = &(style->elemMatch);
|
||||||
|
|||||||
@@ -42,6 +42,9 @@ EXTRA_DIST = \
|
|||||||
test-5.2-16.out test-5.2-16.xml test-5.2-16.xsl \
|
test-5.2-16.out test-5.2-16.xml test-5.2-16.xsl \
|
||||||
test-5.2-17.out test-5.2-17.xml test-5.2-17.xsl \
|
test-5.2-17.out test-5.2-17.xml test-5.2-17.xsl \
|
||||||
test-5.2-18.out test-5.2-18.xml test-5.2-18.xsl \
|
test-5.2-18.out test-5.2-18.xml test-5.2-18.xsl \
|
||||||
|
test-5.2-19.out test-5.2-19.xml test-5.2-19.xsl \
|
||||||
|
test-5.2-20.out test-5.2-20.xml test-5.2-20.xsl \
|
||||||
|
test-5.2-21.out test-5.2-21.xml test-5.2-21.xsl \
|
||||||
test-5.3.out test-5.3.xml test-5.3.xsl \
|
test-5.3.out test-5.3.xml test-5.3.xsl \
|
||||||
test-5.4-1.out test-5.4-1.xml test-5.4-1.xsl \
|
test-5.4-1.out test-5.4-1.xml test-5.4-1.xsl \
|
||||||
test-5.4-2.out test-5.4-2.xml test-5.4-2.xsl \
|
test-5.4-2.out test-5.4-2.xml test-5.4-2.xsl \
|
||||||
|
|||||||
2
tests/REC/test-5.2-19.out
Normal file
2
tests/REC/test-5.2-19.out
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<result>element</result>
|
||||||
4
tests/REC/test-5.2-19.xml
Normal file
4
tests/REC/test-5.2-19.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<root>
|
||||||
|
<element/>
|
||||||
|
</root>
|
||||||
12
tests/REC/test-5.2-19.xsl
Normal file
12
tests/REC/test-5.2-19.xsl
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||||
|
|
||||||
|
<xsl:template match="text()"/>
|
||||||
|
|
||||||
|
<xsl:template match="child::element">
|
||||||
|
<result>
|
||||||
|
<xsl:value-of select="name()"/>
|
||||||
|
</result>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
2
tests/REC/test-5.2-20.out
Normal file
2
tests/REC/test-5.2-20.out
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<result>value</result>
|
||||||
4
tests/REC/test-5.2-20.xml
Normal file
4
tests/REC/test-5.2-20.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<root>
|
||||||
|
<element attribute="value"/>
|
||||||
|
</root>
|
||||||
14
tests/REC/test-5.2-20.xsl
Normal file
14
tests/REC/test-5.2-20.xsl
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||||
|
|
||||||
|
<xsl:template match="*">
|
||||||
|
<xsl:apply-templates select="*|@*"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="@node()">
|
||||||
|
<result>
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</result>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
2
tests/REC/test-5.2-21.out
Normal file
2
tests/REC/test-5.2-21.out
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<result>value</result>
|
||||||
4
tests/REC/test-5.2-21.xml
Normal file
4
tests/REC/test-5.2-21.xml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<root>
|
||||||
|
<element attribute="value"/>
|
||||||
|
</root>
|
||||||
14
tests/REC/test-5.2-21.xsl
Normal file
14
tests/REC/test-5.2-21.xsl
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
||||||
|
|
||||||
|
<xsl:template match="*">
|
||||||
|
<xsl:apply-templates select="*|@*"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="attribute::node()">
|
||||||
|
<result>
|
||||||
|
<xsl:value-of select="."/>
|
||||||
|
</result>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
||||||
Reference in New Issue
Block a user