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

Infrastructure to store extra data in source nodes

Provide a mechanism to store bit flags in nodes from the source
document. This will later be used to store key and id status.

Provide a function to find the psvi member of a node.

Revert any changes to the source document after the transformation.
This commit is contained in:
Nick Wellnhofer
2022-08-31 15:29:57 +02:00
parent 85071e50e6
commit adebe45f6e
4 changed files with 183 additions and 0 deletions

View File

@@ -5746,6 +5746,37 @@ xsltCountKeys(xsltTransformContextPtr ctxt)
return(ctxt->nbKeys);
}
/**
* xsltCleanupSourceDoc:
* @doc: Document
*
* Resets source node flags and ids stored in 'psvi' member.
*/
static void
xsltCleanupSourceDoc(xmlDocPtr doc) {
xmlNodePtr cur = (xmlNodePtr) doc;
void **psviPtr;
while (1) {
xsltClearSourceNodeFlags(cur, XSLT_SOURCE_NODE_MASK);
psviPtr = xsltGetPSVIPtr(cur);
if (psviPtr)
*psviPtr = NULL;
if (cur->children != NULL && cur->type != XML_ENTITY_REF_NODE) {
cur = cur->children;
} else {
while (cur->next == NULL) {
cur = cur->parent;
if (cur == (xmlNodePtr) doc)
return;
}
cur = cur->next;
}
}
}
/**
* xsltApplyStylesheetInternal:
* @style: a parsed XSLT stylesheet
@@ -6144,6 +6175,9 @@ xsltApplyStylesheetInternal(xsltStylesheetPtr style, xmlDocPtr doc,
printf("# Reused variables : %d\n", ctxt->cache->dbgReusedVars);
#endif
if (ctxt->sourceDocDirty)
xsltCleanupSourceDoc(doc);
if ((ctxt != NULL) && (userCtxt == NULL))
xsltFreeTransformContext(ctxt);

View File

@@ -1786,6 +1786,7 @@ struct _xsltTransformContext {
int maxTemplateVars;
unsigned long opLimit;
unsigned long opCount;
int sourceDocDirty;
};
/**

View File

@@ -1834,6 +1834,141 @@ xsltSaveResultToString(xmlChar **doc_txt_ptr, int * doc_txt_len,
return 0;
}
/**
* xsltGetSourceNodeFlags:
* @node: Node from source document
*
* Returns the flags for a source node.
*/
int
xsltGetSourceNodeFlags(xmlNodePtr node) {
/*
* Squeeze the bit flags into the upper bits of
*
* - 'int properties' member in struct _xmlDoc
* - 'xmlAttributeType atype' member in struct _xmlAttr
* - 'unsigned short extra' member in struct _xmlNode
*/
switch (node->type) {
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
return ((xmlDocPtr) node)->properties >> 27;
case XML_ATTRIBUTE_NODE:
return ((xmlAttrPtr) node)->atype >> 27;
case XML_ELEMENT_NODE:
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
return node->extra >> 12;
default:
return 0;
}
}
/**
* xsltSetSourceNodeFlags:
* @node: Node from source document
* @flags: Flags
*
* Sets the specified flags to 1.
*
* Returns 0 on success, -1 on error.
*/
int
xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node,
int flags) {
if (node->doc == ctxt->initialContextDoc)
ctxt->sourceDocDirty = 1;
switch (node->type) {
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
((xmlDocPtr) node)->properties |= flags << 27;
return 0;
case XML_ATTRIBUTE_NODE:
((xmlAttrPtr) node)->atype |= flags << 27;
return 0;
case XML_ELEMENT_NODE:
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
node->extra |= flags << 12;
return 0;
default:
return -1;
}
}
/**
* xsltClearSourceNodeFlags:
* @node: Node from source document
* @flags: Flags
*
* Sets the specified flags to 0.
*
* Returns 0 on success, -1 on error.
*/
int
xsltClearSourceNodeFlags(xmlNodePtr node, int flags) {
switch (node->type) {
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
((xmlDocPtr) node)->properties &= ~(flags << 27);
return 0;
case XML_ATTRIBUTE_NODE:
((xmlAttrPtr) node)->atype &= ~(flags << 27);
return 0;
case XML_ELEMENT_NODE:
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
node->extra &= ~(flags << 12);
return 0;
default:
return -1;
}
}
/**
* xsltGetPSVIPtr:
* @cur: Node
*
* Returns a pointer to the psvi member of a node or NULL on error.
*/
void **
xsltGetPSVIPtr(xmlNodePtr cur) {
switch (cur->type) {
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
return &((xmlDocPtr) cur)->psvi;
case XML_ATTRIBUTE_NODE:
return &((xmlAttrPtr) cur)->psvi;
case XML_ELEMENT_NODE:
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
return &cur->psvi;
default:
return NULL;
}
}
#ifdef WITH_PROFILER
/************************************************************************

View File

@@ -244,6 +244,19 @@ XSLTPUBFUN xmlXPathCompExprPtr XSLTCALL
const xmlChar *str,
int flags);
#ifdef IN_LIBXSLT
#define XSLT_SOURCE_NODE_MASK 15
int
xsltGetSourceNodeFlags(xmlNodePtr node);
int
xsltSetSourceNodeFlags(xsltTransformContextPtr ctxt, xmlNodePtr node,
int flags);
int
xsltClearSourceNodeFlags(xmlNodePtr node, int flags);
void **
xsltGetPSVIPtr(xmlNodePtr cur);
#endif
#ifdef WITH_PROFILER
/*
* Profiling.