1
0
mirror of https://gitlab.gnome.org/GNOME/libxslt synced 2025-11-08 11:02:18 +03:00

More general work, added for-each:

- test/Makefile.am test/REC*/Makefile.am: added first test
- libxslt/pattern.c libxslt/transform.c libxslt/xslt.c:
  cleanup of nodes at reading of stylesheet, added support
  for xsl:for-each and fixed a few recursion bugs
Daniel
This commit is contained in:
Daniel Veillard
2001-01-13 22:29:51 +00:00
parent 26897de4a7
commit ed0f60dea2
10 changed files with 331 additions and 85 deletions

View File

@@ -1,3 +1,10 @@
Sat Jan 13 23:26:21 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* test/Makefile.am test/REC*/Makefile.am: added first test
* libxslt/pattern.c libxslt/transform.c libxslt/xslt.c:
cleanup of nodes at reading of stylesheet, added support
for xsl:for-each and fixed a few recursion bugs
Fri Jan 12 22:33:07 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr> Fri Jan 12 22:33:07 CET 2001 Daniel Veillard <Daniel.Veillard@imag.fr>
* pattern.c, xslt.c: removed debug * pattern.c, xslt.c: removed debug

View File

@@ -24,6 +24,7 @@ xsltConf.sh: xsltConf.sh.in Makefile
< $(srcdir)/xsltConf.sh.in > xsltConf.tmp \ < $(srcdir)/xsltConf.sh.in > xsltConf.tmp \
&& mv xsltConf.tmp xsltConf.sh && mv xsltConf.tmp xsltConf.sh
test:
@(cd tests ; make test)

View File

@@ -120,5 +120,7 @@ Makefile
libxslt/Makefile libxslt/Makefile
libxslt/xsltconfig.h libxslt/xsltconfig.h
tests/Makefile tests/Makefile
tests/REC1/Makefile
tests/REC2/Makefile
xslt-config xslt-config
]) ])

View File

@@ -571,8 +571,8 @@ xsltCompileLocationPathPattern(xsltParserContextPtr ctxt) {
NEXT; NEXT;
SKIP_BLANKS; SKIP_BLANKS;
PUSH(XSLT_OP_ROOT, NULL, NULL); PUSH(XSLT_OP_ROOT, NULL, NULL);
PUSH(XSLT_OP_PARENT, NULL, NULL);
if ((CUR != 0) || (CUR == '|')) { if ((CUR != 0) || (CUR == '|')) {
PUSH(XSLT_OP_PARENT, NULL, NULL);
xsltCompileRelativePathPattern(ctxt, NULL); xsltCompileRelativePathPattern(ctxt, NULL);
} }
} else { } else {

View File

@@ -89,7 +89,6 @@ struct _xsltTransformContext {
xmlNodePtr insert; /* the insertion node */ xmlNodePtr insert; /* the insertion node */
xmlXPathContextPtr xpathCtxt; /* the XPath context */ xmlXPathContextPtr xpathCtxt; /* the XPath context */
xmlXPathParserContextPtr xpathParserCtxt;/* the XPath parser context */
}; };
/************************************************************************ /************************************************************************
@@ -142,6 +141,8 @@ xsltFreeTransformContext(xsltTransformContextPtr ctxt) {
************************************************************************/ ************************************************************************/
void xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node); void xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node);
void xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst);
/** /**
* xsltValueOf: * xsltValueOf:
@@ -157,6 +158,7 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlChar *prop; xmlChar *prop;
int disableEscaping = 0; int disableEscaping = 0;
xmlXPathObjectPtr res, tmp; xmlXPathObjectPtr res, tmp;
xmlXPathParserContextPtr xpathParserCtxt;
xmlNodePtr copy = NULL; xmlNodePtr copy = NULL;
if ((ctxt == NULL) || (node == NULL) || (inst == NULL)) if ((ctxt == NULL) || (node == NULL) || (inst == NULL))
@@ -181,7 +183,7 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
prop = xmlGetNsProp(inst, (const xmlChar *)"select", XSLT_NAMESPACE); prop = xmlGetNsProp(inst, (const xmlChar *)"select", XSLT_NAMESPACE);
if (prop == NULL) { if (prop == NULL) {
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsltValueOf: select is not defined\n", prop); "xsltValueOf: select is not defined\n");
return; return;
} }
#ifdef DEBUG_PROCESS #ifdef DEBUG_PROCESS
@@ -195,17 +197,17 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
if (ctxt->xpathCtxt == NULL) if (ctxt->xpathCtxt == NULL)
goto error; goto error;
} }
ctxt->xpathParserCtxt = xpathParserCtxt =
xmlXPathNewParserContext(prop, ctxt->xpathCtxt); xmlXPathNewParserContext(prop, ctxt->xpathCtxt);
if (ctxt->xpathParserCtxt == NULL) if (xpathParserCtxt == NULL)
goto error; goto error;
ctxt->xpathCtxt->node = node; ctxt->xpathCtxt->node = node;
valuePush(ctxt->xpathParserCtxt, xmlXPathNewNodeSet(node)); valuePush(xpathParserCtxt, xmlXPathNewNodeSet(node));
xmlXPathEvalExpr(ctxt->xpathParserCtxt); xmlXPathEvalExpr(xpathParserCtxt);
xmlXPathStringFunction(ctxt->xpathParserCtxt, 1); xmlXPathStringFunction(xpathParserCtxt, 1);
res = valuePop(ctxt->xpathParserCtxt); res = valuePop(xpathParserCtxt);
do { do {
tmp = valuePop(ctxt->xpathParserCtxt); tmp = valuePop(xpathParserCtxt);
if (tmp != NULL) { if (tmp != NULL) {
xmlXPathFreeObject(tmp); xmlXPathFreeObject(tmp);
} }
@@ -228,8 +230,10 @@ xsltValueOf(xsltTransformContextPtr ctxt, xmlNodePtr node,
"xsltValueOf: result %s\n", res->stringval); "xsltValueOf: result %s\n", res->stringval);
#endif #endif
error: error:
if (ctxt->xpathParserCtxt != NULL) if (xpathParserCtxt != NULL) {
xmlXPathFreeParserContext(ctxt->xpathParserCtxt); xmlXPathFreeParserContext(xpathParserCtxt);
xpathParserCtxt = NULL;
}
if (prop != NULL) if (prop != NULL)
xmlFree(prop); xmlFree(prop);
if (res != NULL) if (res != NULL)
@@ -253,6 +257,7 @@ xsltCopyNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr copy; xmlNodePtr copy;
copy = xmlCopyNode(node, 0); copy = xmlCopyNode(node, 0);
copy->doc = ctxt->output;
if (copy != NULL) { if (copy != NULL) {
xmlAddChild(insert, copy); xmlAddChild(insert, copy);
/* /*
@@ -290,7 +295,7 @@ xsltCopyNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
} }
} else { } else {
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsltProcessOneNode: copy %s failed\n", node->name); "xsltCopyNode: copy %s failed\n", node->name);
} }
return(copy); return(copy);
} }
@@ -319,6 +324,7 @@ xsltCopyNode(xsltTransformContextPtr ctxt, xmlNodePtr node,
void void
xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
xmlNodePtr copy; xmlNodePtr copy;
xmlNodePtr delete = NULL;
switch (node->type) { switch (node->type) {
case XML_DOCUMENT_NODE: case XML_DOCUMENT_NODE:
@@ -347,9 +353,11 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
xmlHashLookup(ctxt->style->stripSpaces, xmlHashLookup(ctxt->style->stripSpaces,
node->parent->name); node->parent->name);
if ((val != NULL) && if ((val != NULL) &&
(xmlStrEqual(val, (xmlChar *) "strip"))) (xmlStrEqual(val, (xmlChar *) "strip"))) {
delete = node;
break; break;
} }
}
/* no break on purpose */ /* no break on purpose */
case XML_CDATA_SECTION_NODE: case XML_CDATA_SECTION_NODE:
copy = xmlCopyNode(node, 0); copy = xmlCopyNode(node, 0);
@@ -361,9 +369,23 @@ xsltDefaultProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
} }
break; break;
default: default:
TODO #ifdef DEBUG_PROCESS
xsltGenericError(xsltGenericErrorContext,
"xsltDefaultProcessOneNode: skipping node type %d\n",
node->type);
#endif
delete = node;
} }
node = node->next; node = node->next;
if (delete != NULL) {
#ifdef DEBUG_PROCESS
xsltGenericError(xsltGenericErrorContext,
"xsltDefaultProcessOneNode: removing ignorable blank node\n");
#endif
xmlUnlinkNode(delete);
xmlFreeNode(delete);
delete = NULL;
}
} }
} }
@@ -396,38 +418,48 @@ xsltApplyTemplates(xsltTransformContextPtr ctxt, xmlNodePtr node,
} }
/** /**
* xsltProcessOneNode: * xsltApplyOneTemplate:
* @ctxt: a XSLT process context * @ctxt: a XSLT process context
* @node: the node in the source tree. * @node: the node in the source tree.
* @list: the template replacement nodelist
* *
* Process the source node. * Process the apply-templates node on the source node
*/ */
void void
xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) { xsltApplyOneTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
xsltTemplatePtr template; xmlNodePtr list) {
xmlNodePtr cur, insert, copy; xmlNodePtr cur, insert, copy, delete = NULL;
xmlNodePtr oldInsert; xmlNodePtr oldInsert;
oldInsert = insert = ctxt->insert; oldInsert = insert = ctxt->insert;
template = xsltGetTemplate(ctxt->style, node);
/* /*
* If no template is found, apply the deafult rule. * Insert all non-XSLT nodes found in the template
*/ */
if (template == NULL) { cur = list;
while (cur != NULL) {
/*
* test, we must have a valid insertion point
*/
if (insert == NULL) {
#ifdef DEBUG_PROCESS #ifdef DEBUG_PROCESS
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsltProcessOneNode: no template found for %s\n", node->name); "xsltApplyOneTemplate: insert == NULL !\n");
#endif #endif
xsltDefaultProcessOneNode(ctxt, node);
return; return;
} }
/* /*
* Insert all non-XSLT nodes found in the template * Cleanup of ignorable blank node detected
*/ */
cur = template->content; if (delete != NULL) {
while (cur != NULL) { #ifdef DEBUG_PROCESS
xsltGenericError(xsltGenericErrorContext,
"xsltApplyOneTemplate: removing ignorable blank node\n");
#endif
xmlUnlinkNode(delete);
xmlFreeNode(delete);
delete = NULL;
}
if (IS_XSLT_ELEM(cur)) { if (IS_XSLT_ELEM(cur)) {
if (IS_XSLT_NAME(cur, "apply-templates")) { if (IS_XSLT_NAME(cur, "apply-templates")) {
ctxt->insert = insert; ctxt->insert = insert;
@@ -437,13 +469,18 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
ctxt->insert = insert; ctxt->insert = insert;
xsltValueOf(ctxt, node, cur); xsltValueOf(ctxt, node, cur);
ctxt->insert = oldInsert; ctxt->insert = oldInsert;
} else if (IS_XSLT_NAME(cur, "for-each")) {
ctxt->insert = insert;
xsltForEach(ctxt, node, cur);
ctxt->insert = oldInsert;
} else { } else {
#ifdef DEBUG_PROCESS #ifdef DEBUG_PROCESS
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsltProcessOneNode: found xslt:%s\n", cur->name); "xsltApplyOneTemplate: found xslt:%s\n", cur->name);
#endif #endif
TODO TODO
} }
goto skip_children;
} else if (cur->type == XML_TEXT_NODE) { } else if (cur->type == XML_TEXT_NODE) {
/* /*
* This text comes from the stylesheet * This text comes from the stylesheet
@@ -453,20 +490,22 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
if (!(IS_BLANK_NODE(cur))) { if (!(IS_BLANK_NODE(cur))) {
#ifdef DEBUG_PROCESS #ifdef DEBUG_PROCESS
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsltProcessOneNode: copy text %s\n", cur->content); "xsltApplyOneTemplate: copy text %s\n", cur->content);
#endif #endif
copy = xmlCopyNode(cur, 0); copy = xmlCopyNode(cur, 0);
if (copy != NULL) { if (copy != NULL) {
xmlAddChild(insert, copy); xmlAddChild(insert, copy);
} else { } else {
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsltProcessOneNode: text copy failed\n"); "xsltApplyOneTemplate: text copy failed\n");
}
} }
} else { } else {
delete = cur;
}
} else if (cur->type == XML_ELEMENT_NODE) {
#ifdef DEBUG_PROCESS #ifdef DEBUG_PROCESS
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsltProcessOneNode: copy node %s\n", cur->name); "xsltApplyOneTemplate: copy node %s\n", cur->name);
#endif #endif
copy = xsltCopyNode(ctxt, cur, insert); copy = xsltCopyNode(ctxt, cur, insert);
/* /*
@@ -476,17 +515,19 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
if (cur->properties != NULL) if (cur->properties != NULL)
copy->properties = xmlCopyPropList(copy, cur->properties); copy->properties = xmlCopyPropList(copy, cur->properties);
} }
/*
* Skip to next node
*/
/*
* Skip to next node, in document order.
*/
if (cur->children != NULL) { if (cur->children != NULL) {
if (cur->children->type != XML_ENTITY_DECL) { if (cur->children->type != XML_ENTITY_DECL) {
cur = cur->children; cur = cur->children;
if (copy != NULL)
insert = copy; insert = copy;
continue; continue;
} }
} }
skip_children:
if (cur->next != NULL) { if (cur->next != NULL) {
cur = cur->next; cur = cur->next;
continue; continue;
@@ -497,7 +538,7 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
insert = insert->parent; insert = insert->parent;
if (cur == NULL) if (cur == NULL)
break; break;
if (cur == template->content) { if (cur == list->parent) {
cur = NULL; cur = NULL;
break; break;
} }
@@ -507,13 +548,126 @@ xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
} }
} while (cur != NULL); } while (cur != NULL);
} }
/********
if (ctxt->style->indent) {
copy = xmlNewText("\n");
if (copy != NULL)
xmlAddChild(ctxt->insert, copy);
} }
********/
/**
* xsltForEach:
* @ctxt: a XSLT process context
* @node: the node in the source tree.
* @inst: the xslt for-each node
*
* Process the xslt for-each node on the source node
*/
void
xsltForEach(xsltTransformContextPtr ctxt, xmlNodePtr node,
xmlNodePtr inst) {
xmlChar *prop;
xmlXPathObjectPtr res, tmp;
xmlNodePtr replacement;
xmlNodeSetPtr list = NULL, oldlist;
xmlXPathParserContextPtr xpathParserCtxt;
int i;
if ((ctxt == NULL) || (node == NULL) || (inst == NULL))
return;
prop = xmlGetNsProp(inst, (const xmlChar *)"select", XSLT_NAMESPACE);
if (prop == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltForEach: select is not defined\n");
return;
}
#ifdef DEBUG_PROCESS
xsltGenericError(xsltGenericErrorContext,
"xsltForEach: select %s\n", prop);
#endif
if (ctxt->xpathCtxt == NULL) {
xmlXPathInit();
ctxt->xpathCtxt = xmlXPathNewContext(ctxt->doc);
if (ctxt->xpathCtxt == NULL)
goto error;
}
xpathParserCtxt = xmlXPathNewParserContext(prop, ctxt->xpathCtxt);
if (xpathParserCtxt == NULL)
goto error;
ctxt->xpathCtxt->node = node;
valuePush(xpathParserCtxt, xmlXPathNewNodeSet(node));
xmlXPathEvalExpr(xpathParserCtxt);
res = valuePop(xpathParserCtxt);
do {
tmp = valuePop(xpathParserCtxt);
if (tmp != NULL) {
xmlXPathFreeObject(tmp);
}
} while (tmp != NULL);
if (res != NULL) {
if (res->type == XPATH_NODESET)
list = res->nodesetval;
else {
#ifdef DEBUG_PROCESS
xsltGenericError(xsltGenericErrorContext,
"xsltForEach: select didn't evaluate to a node list\n");
#endif
goto error;
}
}
#ifdef DEBUG_PROCESS
xsltGenericError(xsltGenericErrorContext,
"xsltForEach: select evaluate to %d nodes\n", list->nodeNr);
#endif
/* TODO: handle and skip the xsl:sort */
replacement = inst->children;
oldlist = ctxt->nodeList;
ctxt->nodeList = list;
for (i = 0;i < list->nodeNr;i++) {
ctxt->node = list->nodeTab[i];
xsltApplyOneTemplate(ctxt, list->nodeTab[i], replacement);
}
ctxt->nodeList = oldlist;
error:
if (xpathParserCtxt != NULL)
xmlXPathFreeParserContext(xpathParserCtxt);
if (prop != NULL)
xmlFree(prop);
if (res != NULL)
xmlXPathFreeObject(res);
}
/**
* xsltProcessOneNode:
* @ctxt: a XSLT process context
* @node: the node in the source tree.
*
* Process the source node.
*/
void
xsltProcessOneNode(xsltTransformContextPtr ctxt, xmlNodePtr node) {
xsltTemplatePtr template;
template = xsltGetTemplate(ctxt->style, node);
/*
* If no template is found, apply the default rule.
*/
if (template == NULL) {
#ifdef DEBUG_PROCESS
if (node->type == XML_DOCUMENT_NODE)
xsltGenericError(xsltGenericErrorContext,
"xsltProcessOneNode: no template found for /\n");
else
xsltGenericError(xsltGenericErrorContext,
"xsltProcessOneNode: no template found for %s\n", node->name);
#endif
xsltDefaultProcessOneNode(ctxt, node);
return;
}
xsltApplyOneTemplate(ctxt, node, template->content);
} }
/** /**
@@ -569,17 +723,10 @@ xsltApplyStylesheet(xsltStylesheetPtr style, xmlDocPtr doc) {
/* /*
* Start. * Start.
*/ */
root = xmlDocGetRootElement(doc);
if (root == NULL) {
xsltGenericError(xsltGenericErrorContext,
"xsltApplyStylesheet: document has no root\n");
goto error;
}
ctxt->output = res; ctxt->output = res;
ctxt->insert = (xmlNodePtr) res; ctxt->insert = (xmlNodePtr) res;
ctxt->node = root; ctxt->node = (xmlNodePtr) doc;
ctxt->nodeList = xmlXPathNodeSetCreate(root); xsltProcessOneNode(ctxt, ctxt->node);
xsltProcessOneNode(ctxt, root);
if ((ctxt->type = XSLT_OUTPUT_XML) && if ((ctxt->type = XSLT_OUTPUT_XML) &&

View File

@@ -477,7 +477,7 @@ xsltParseStylesheetStripSpace(xsltStylesheetPtr style, xmlNodePtr cur) {
void void
xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) { xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
xsltTemplatePtr ret; xsltTemplatePtr ret;
xmlNodePtr cur; xmlNodePtr cur, delete;
xmlChar *prop; xmlChar *prop;
if (template == NULL) if (template == NULL)
@@ -539,6 +539,65 @@ xsltParseStylesheetTemplate(xsltStylesheetPtr style, xmlNodePtr template) {
} }
} }
/*
* Clean-up the template content from unwanted ignorable blank nodes
* This content comes from the stylesheet
* For stylesheets, the set of whitespace-preserving
* element names consists of just xsl:text.
*/
cur = template->children;
delete = NULL;
while (cur != NULL) {
if (delete != NULL) {
#ifdef DEBUG_PARSING
xsltGenericError(xsltGenericErrorContext,
"xsltParseStylesheetTemplate: removing ignorable blank node\n");
#endif
xmlUnlinkNode(delete);
xmlFreeNode(delete);
delete = NULL;
}
if (IS_XSLT_ELEM(cur)) {
if (IS_XSLT_NAME(cur, "text"))
goto skip_children;
} else if (cur->type == XML_TEXT_NODE) {
if (IS_BLANK_NODE(cur)) {
delete = cur;
}
} else if (cur->type != XML_ELEMENT_NODE) {
delete = cur;
}
/*
* Skip to next node
*/
if (cur->children != NULL) {
if (cur->children->type != XML_ENTITY_DECL) {
cur = cur->children;
continue;
}
}
skip_children:
if (cur->next != NULL) {
cur = cur->next;
continue;
}
do {
cur = cur->parent;
if (cur == NULL)
break;
if (cur == template) {
cur = NULL;
break;
}
if (cur->next != NULL) {
cur = cur->next;
break;
}
} while (cur != NULL);
}
/* /*
* Find and handle the params * Find and handle the params
*/ */
@@ -726,22 +785,24 @@ xsltParseStylesheetDoc(xmlDocPtr doc) {
return(NULL); return(NULL);
} }
ret->doc = doc;
if ((IS_XSLT_ELEM(cur)) && (IS_XSLT_NAME(cur, "stylesheet"))) { if ((IS_XSLT_ELEM(cur)) && (IS_XSLT_NAME(cur, "stylesheet"))) {
#ifdef DEBUG_PARSING #ifdef DEBUG_PARSING
xsltGenericError(xsltGenericErrorContext, xsltGenericError(xsltGenericErrorContext,
"xsltParseStylesheetDoc : found stylesheet\n"); "xsltParseStylesheetDoc : found stylesheet\n");
#endif #endif
} else {
TODO /* lookup the stylesheet element down in the tree */
xsltGenericError(xsltGenericErrorContext,
"xsltParseStylesheetDoc : root is not stylesheet\n");
xsltFreeStylesheet(ret);
return(NULL);
}
ret->doc = doc;
xsltParseStylesheetTop(ret, cur); xsltParseStylesheetTop(ret, cur);
} else {
/*
* the document itself is the template.
*/
#ifdef DEBUG_PARSING
xsltGenericError(xsltGenericErrorContext,
"xsltParseStylesheetDoc : document is stylesheet\n");
#endif
TODO
}
return(ret); return(ret);
} }

View File

@@ -17,3 +17,7 @@ LDADDS = $(top_builddir)/libxslt/libxslt.la $(LIBXML_LIBS)
#testevents_LDFLAGS = #testevents_LDFLAGS =
#testevents_DEPENDENCIES = $(DEPS) #testevents_DEPENDENCIES = $(DEPS)
#testevents_LDADD = $(LDADDS) #testevents_LDADD = $(LDADDS)
test: $(top_builddir)/libxslt/xsltproc
@(cd REC1 ; make test)
@(cd REC2 ; make test)

13
tests/REC1/Makefile.am Normal file
View File

@@ -0,0 +1,13 @@
## Process this file with automake to produce Makefile.in
$(top_builddir)/libxslt/xsltproc:
@(cd ../../libxslt ; make xsltproc)
test: $(top_builddir)/libxslt/xsltproc
@(rm -f .memdump ; touch .memdump)
@($(top_builddir)/libxslt/xsltproc doc.xsl doc.xml > doc.res ; \
diff result.xml doc.res ; \
grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\
rm -f doc.res)

View File

@@ -8,11 +8,9 @@
<h2>Chapter Title</h2> <h2>Chapter Title</h2>
<h3>Section Title</h3> <h3>Section Title</h3>
<p>This is a test.</p> <p>This is a test.</p>
<p class="note"> <p class="note"><b>NOTE: </b>This is a note.</p>
<b>NOTE: </b>This is a note.</p>
<h3>Another Section Title</h3> <h3>Another Section Title</h3>
<p>This is <em>another</em> test.</p> <p>This is <em>another</em> test.</p>
<p class="note"> <p class="note"><b>NOTE: </b>This is another note.</p>
<b>NOTE: </b>This is another note.</p>
</body> </body>
</html> </html>

13
tests/REC2/Makefile.am Normal file
View File

@@ -0,0 +1,13 @@
## Process this file with automake to produce Makefile.in
$(top_builddir)/libxslt/xsltproc:
@(cd ../../libxslt ; make xsltproc)
test: $(top_builddir)/libxslt/xsltproc
@(rm -f .memdump ; touch .memdump)
@($(top_builddir)/libxslt/xsltproc doc.xsl doc.xml > doc.res ; \
diff result.xml doc.res ; \
grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0";\
rm -f doc.res)