mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-07-29 11:41:22 +03:00
XInclude and other stuff while travelling. Contributed patches:
- tree.[ch] xinclude.[ch] xmllint.c configure.in valid.c debugXML.c xmlversion.h.in: Started adding XInclude support, this is a new xmllint option - tree.c xpath.c: applied TOM patches for XPath - xpointer.c: fixed a couple of errors. - uri.c: added an escaping function needed for xinclude - testXPath.c hash.c HTMLtree.c: minor cleanups raised by new warning from RH70 gcc's version Daniel
This commit is contained in:
11
ChangeLog
11
ChangeLog
@ -1,3 +1,14 @@
|
|||||||
|
Mon Nov 6 17:22:46 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
|
||||||
|
|
||||||
|
* tree.[ch] xinclude.[ch] xmllint.c configure.in valid.c
|
||||||
|
debugXML.c xmlversion.h.in: Started adding XInclude support,
|
||||||
|
this is a new xmllint option
|
||||||
|
* tree.c xpath.c: applied TOM patches for XPath
|
||||||
|
* xpointer.c: fixed a couple of errors.
|
||||||
|
* uri.c: added an escaping function needed for xinclude
|
||||||
|
* testXPath.c hash.c HTMLtree.c: minor cleanups raised by
|
||||||
|
new warning from RH70 gcc's version
|
||||||
|
|
||||||
Tue Oct 31 14:14:13 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
|
Tue Oct 31 14:14:13 CET 2000 Daniel Veillard <Daniel.Veillard@w3.org>
|
||||||
|
|
||||||
* HTMLparser.c: fixed loop on invalid char in scripts
|
* HTMLparser.c: fixed loop on invalid char in scripts
|
||||||
|
@ -818,7 +818,8 @@ htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, const
|
|||||||
#ifndef XML_USE_BUFFER_CONTENT
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
xmlOutputBufferWriteString(buf, (const char *)cur->content);
|
xmlOutputBufferWriteString(buf, (const char *)cur->content);
|
||||||
#else
|
#else
|
||||||
xmlOutputBufferWriteString(buf, xmlBufferContent(cur->content));
|
xmlOutputBufferWriteString(buf, (const char *)
|
||||||
|
xmlBufferContent(cur->content));
|
||||||
#endif
|
#endif
|
||||||
xmlOutputBufferWriteString(buf, "-->");
|
xmlOutputBufferWriteString(buf, "-->");
|
||||||
}
|
}
|
||||||
@ -835,7 +836,8 @@ htmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, const
|
|||||||
#ifndef XML_USE_BUFFER_CONTENT
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
xmlOutputBufferWriteString(buf, (const char *)cur->content);
|
xmlOutputBufferWriteString(buf, (const char *)cur->content);
|
||||||
#else
|
#else
|
||||||
xmlOutputBufferWriteString(buf, xmlBufferContent(cur->content));
|
xmlOutputBufferWriteString(buf, (const char *)
|
||||||
|
xmlBufferContent(cur->content));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -34,6 +34,7 @@ libxml_la_SOURCES = \
|
|||||||
debugXML.c \
|
debugXML.c \
|
||||||
xpath.c \
|
xpath.c \
|
||||||
xpointer.c \
|
xpointer.c \
|
||||||
|
xinclude.c \
|
||||||
nanohttp.c \
|
nanohttp.c \
|
||||||
nanoftp.c
|
nanoftp.c
|
||||||
|
|
||||||
|
13
configure.in
13
configure.in
@ -286,6 +286,19 @@ fi
|
|||||||
AC_SUBST(WITH_XPTR)
|
AC_SUBST(WITH_XPTR)
|
||||||
AC_SUBST(XPTR_OBJ)
|
AC_SUBST(XPTR_OBJ)
|
||||||
|
|
||||||
|
AC_ARG_WITH(xinclude, [ --with-xinclude Add the XInclude support (on)])
|
||||||
|
if test "$with_xinclude" = "no" ; then
|
||||||
|
echo Disabling XInclude support
|
||||||
|
WITH_XINCLUDE=0
|
||||||
|
XINCLUDE_OBJ=
|
||||||
|
with_xinclude="no"
|
||||||
|
else
|
||||||
|
WITH_XINCLUDE=1
|
||||||
|
XINCLUDE_OBJ=xinclude.o
|
||||||
|
fi
|
||||||
|
AC_SUBST(WITH_XINCLUDE)
|
||||||
|
AC_SUBST(XINCLUDE_OBJ)
|
||||||
|
|
||||||
AC_ARG_WITH(iconv, [ --with-iconv Add the ICONV support (on)])
|
AC_ARG_WITH(iconv, [ --with-iconv Add the ICONV support (on)])
|
||||||
if test "$with_iconv" = "no" ; then
|
if test "$with_iconv" = "no" ; then
|
||||||
echo Disabling ICONV support
|
echo Disabling ICONV support
|
||||||
|
11
debugXML.c
11
debugXML.c
@ -559,6 +559,7 @@ void xmlDebugDumpOneNode(FILE *output, xmlNodePtr node, int depth) {
|
|||||||
fprintf(output, "DOCUMENT_FRAG\n");
|
fprintf(output, "DOCUMENT_FRAG\n");
|
||||||
break;
|
break;
|
||||||
case XML_NOTATION_NODE:
|
case XML_NOTATION_NODE:
|
||||||
|
fprintf(output, shift);
|
||||||
fprintf(output, "NOTATION\n");
|
fprintf(output, "NOTATION\n");
|
||||||
break;
|
break;
|
||||||
case XML_DTD_NODE:
|
case XML_DTD_NODE:
|
||||||
@ -576,6 +577,14 @@ void xmlDebugDumpOneNode(FILE *output, xmlNodePtr node, int depth) {
|
|||||||
case XML_NAMESPACE_DECL:
|
case XML_NAMESPACE_DECL:
|
||||||
xmlDebugDumpNamespace(output, (xmlNsPtr) node, depth);
|
xmlDebugDumpNamespace(output, (xmlNsPtr) node, depth);
|
||||||
return;
|
return;
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
fprintf(output, shift);
|
||||||
|
fprintf(output, "INCLUDE START\n");
|
||||||
|
return;
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
|
fprintf(output, shift);
|
||||||
|
fprintf(output, "INCLUDE END\n");
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
fprintf(output, shift);
|
fprintf(output, shift);
|
||||||
fprintf(output, "NODE_%d !!!\n", node->type);
|
fprintf(output, "NODE_%d !!!\n", node->type);
|
||||||
@ -917,6 +926,8 @@ static int xmlLsCountNode(xmlNodePtr node) {
|
|||||||
case XML_ATTRIBUTE_DECL:
|
case XML_ATTRIBUTE_DECL:
|
||||||
case XML_ENTITY_DECL:
|
case XML_ENTITY_DECL:
|
||||||
case XML_NAMESPACE_DECL:
|
case XML_NAMESPACE_DECL:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
1
hash.c
1
hash.c
@ -17,6 +17,7 @@
|
|||||||
* Author: bjorn.reese@systematic.dk
|
* Author: bjorn.reese@systematic.dk
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
#include <libxml/hash.h>
|
#include <libxml/hash.h>
|
||||||
#include <libxml/xmlmemory.h>
|
#include <libxml/xmlmemory.h>
|
||||||
#include <libxml/parser.h>
|
#include <libxml/parser.h>
|
||||||
|
@ -41,9 +41,11 @@ typedef enum {
|
|||||||
XML_ELEMENT_DECL= 15,
|
XML_ELEMENT_DECL= 15,
|
||||||
XML_ATTRIBUTE_DECL= 16,
|
XML_ATTRIBUTE_DECL= 16,
|
||||||
XML_ENTITY_DECL= 17,
|
XML_ENTITY_DECL= 17,
|
||||||
XML_NAMESPACE_DECL= 18
|
XML_NAMESPACE_DECL= 18,
|
||||||
|
XML_XINCLUDE_START= 19,
|
||||||
|
XML_XINCLUDE_END= 20
|
||||||
#ifdef LIBXML_SGML_ENABLED
|
#ifdef LIBXML_SGML_ENABLED
|
||||||
,XML_SGML_DOCUMENT_NODE= 19
|
,XML_SGML_DOCUMENT_NODE= 21
|
||||||
#endif
|
#endif
|
||||||
} xmlElementType;
|
} xmlElementType;
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ char * xmlURIUnescapeString (const char *str,
|
|||||||
int len,
|
int len,
|
||||||
char *target);
|
char *target);
|
||||||
int xmlNormalizeURIPath (char *path);
|
int xmlNormalizeURIPath (char *path);
|
||||||
|
xmlChar * xmlURIEscape (const xmlChar *str);
|
||||||
void xmlFreeURI (xmlURIPtr uri);
|
void xmlFreeURI (xmlURIPtr uri);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
26
include/libxml/xinclude.h
Normal file
26
include/libxml/xinclude.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* xinclude.c : API to handle XInclude processing
|
||||||
|
*
|
||||||
|
* World Wide Web Consortium Working Draft 26 October 2000
|
||||||
|
* http://www.w3.org/TR/2000/WD-xinclude-20001026
|
||||||
|
*
|
||||||
|
* See Copyright for the status of this software.
|
||||||
|
*
|
||||||
|
* Daniel.Veillard@w3.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XML_XINCLUDE_H__
|
||||||
|
#define __XML_XINCLUDE_H__
|
||||||
|
|
||||||
|
#include <libxml/tree.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int xmlXIncludeProcess (xmlDocPtr doc);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* __XML_XINCLUDE_H__ */
|
@ -77,6 +77,15 @@ extern void xmlCheckVersion(int version);
|
|||||||
#define LIBXML_XPTR_DISABLED
|
#define LIBXML_XPTR_DISABLED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Whether XInclude is configured in
|
||||||
|
*/
|
||||||
|
#if @WITH_XINCLUDE@
|
||||||
|
#define LIBXML_XINCLUDE_ENABLED
|
||||||
|
#else
|
||||||
|
#define LIBXML_XINCLUDE_DISABLED
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Whether iconv support is available
|
* Whether iconv support is available
|
||||||
*/
|
*/
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include <libxml/debugXML.h>
|
#include <libxml/debugXML.h>
|
||||||
#include <libxml/xmlmemory.h>
|
#include <libxml/xmlmemory.h>
|
||||||
#include <libxml/parserInternals.h>
|
#include <libxml/parserInternals.h>
|
||||||
|
#include <libxml/xpathInternals.h>
|
||||||
#include <libxml/xmlerror.h>
|
#include <libxml/xmlerror.h>
|
||||||
#if defined(LIBXML_XPTR_ENABLED)
|
#if defined(LIBXML_XPTR_ENABLED)
|
||||||
#include <libxml/xpointer.h>
|
#include <libxml/xpointer.h>
|
||||||
|
218
tree.c
218
tree.c
@ -45,12 +45,16 @@ int xmlSaveNoEmptyTags = 0;
|
|||||||
#define IS_BLANK(c) \
|
#define IS_BLANK(c) \
|
||||||
(((c) == '\n') || ((c) == '\r') || ((c) == '\t') || ((c) == ' '))
|
(((c) == '\n') || ((c) == '\r') || ((c) == '\t') || ((c) == ' '))
|
||||||
|
|
||||||
#define UPDATE_LAST_CHILD(n) if ((n) != NULL) { \
|
#define UPDATE_LAST_CHILD_AND_PARENT(n) if ((n) != NULL) { \
|
||||||
xmlNodePtr ulccur = (n)->children; \
|
xmlNodePtr ulccur = (n)->children; \
|
||||||
if (ulccur == NULL) { \
|
if (ulccur == NULL) { \
|
||||||
(n)->last = NULL; \
|
(n)->last = NULL; \
|
||||||
} else { \
|
} else { \
|
||||||
while (ulccur->next != NULL) ulccur = ulccur->next; \
|
while (ulccur->next != NULL) { \
|
||||||
|
ulccur->parent = (n); \
|
||||||
|
ulccur = ulccur->next; \
|
||||||
|
} \
|
||||||
|
ulccur->parent = (n); \
|
||||||
(n)->last = ulccur; \
|
(n)->last = ulccur; \
|
||||||
}}
|
}}
|
||||||
|
|
||||||
@ -892,6 +896,7 @@ xmlNewProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
|
|||||||
|
|
||||||
buffer = xmlEncodeEntitiesReentrant(node->doc, value);
|
buffer = xmlEncodeEntitiesReentrant(node->doc, value);
|
||||||
cur->children = xmlStringGetNodeList(node->doc, buffer);
|
cur->children = xmlStringGetNodeList(node->doc, buffer);
|
||||||
|
cur->last = NULL;
|
||||||
tmp = cur->children;
|
tmp = cur->children;
|
||||||
while (tmp != NULL) {
|
while (tmp != NULL) {
|
||||||
tmp->parent = (xmlNodePtr) cur;
|
tmp->parent = (xmlNodePtr) cur;
|
||||||
@ -965,6 +970,7 @@ xmlNewNsProp(xmlNodePtr node, xmlNsPtr ns, const xmlChar *name,
|
|||||||
|
|
||||||
buffer = xmlEncodeEntitiesReentrant(node->doc, value);
|
buffer = xmlEncodeEntitiesReentrant(node->doc, value);
|
||||||
cur->children = xmlStringGetNodeList(node->doc, buffer);
|
cur->children = xmlStringGetNodeList(node->doc, buffer);
|
||||||
|
cur->last = NULL;
|
||||||
tmp = cur->children;
|
tmp = cur->children;
|
||||||
while (tmp != NULL) {
|
while (tmp != NULL) {
|
||||||
tmp->parent = (xmlNodePtr) cur;
|
tmp->parent = (xmlNodePtr) cur;
|
||||||
@ -1027,8 +1033,20 @@ xmlNewDocProp(xmlDocPtr doc, const xmlChar *name, const xmlChar *value) {
|
|||||||
|
|
||||||
cur->name = xmlStrdup(name);
|
cur->name = xmlStrdup(name);
|
||||||
cur->doc = doc;
|
cur->doc = doc;
|
||||||
if (value != NULL)
|
if (value != NULL) {
|
||||||
|
xmlNodePtr tmp;
|
||||||
|
|
||||||
cur->children = xmlStringGetNodeList(doc, value);
|
cur->children = xmlStringGetNodeList(doc, value);
|
||||||
|
cur->last = NULL;
|
||||||
|
|
||||||
|
tmp = cur->children;
|
||||||
|
while (tmp != NULL) {
|
||||||
|
tmp->parent = (xmlNodePtr) cur;
|
||||||
|
if (tmp->next == NULL)
|
||||||
|
cur->last = tmp;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
return(cur);
|
return(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1239,7 +1257,7 @@ xmlNewDocNode(xmlDocPtr doc, xmlNsPtr ns,
|
|||||||
cur->doc = doc;
|
cur->doc = doc;
|
||||||
if (content != NULL) {
|
if (content != NULL) {
|
||||||
cur->children = xmlStringGetNodeList(doc, content);
|
cur->children = xmlStringGetNodeList(doc, content);
|
||||||
UPDATE_LAST_CHILD(cur)
|
UPDATE_LAST_CHILD_AND_PARENT(cur)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(cur);
|
return(cur);
|
||||||
@ -1268,7 +1286,7 @@ xmlNewDocRawNode(xmlDocPtr doc, xmlNsPtr ns,
|
|||||||
cur->doc = doc;
|
cur->doc = doc;
|
||||||
if (content != NULL) {
|
if (content != NULL) {
|
||||||
cur->children = xmlNewDocText(doc, content);
|
cur->children = xmlNewDocText(doc, content);
|
||||||
UPDATE_LAST_CHILD(cur)
|
UPDATE_LAST_CHILD_AND_PARENT(cur)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(cur);
|
return(cur);
|
||||||
@ -1491,7 +1509,13 @@ xmlNewReference(xmlDocPtr doc, const xmlChar *name) {
|
|||||||
if (ent->content != NULL)
|
if (ent->content != NULL)
|
||||||
xmlBufferAdd(cur->content, ent->content, -1);
|
xmlBufferAdd(cur->content, ent->content, -1);
|
||||||
#endif
|
#endif
|
||||||
|
/*
|
||||||
|
* The parent pointer in entity is a Dtd pointer and thus is NOT
|
||||||
|
* updated. Not sure if this is 100% correct.
|
||||||
|
* -George
|
||||||
|
*/
|
||||||
cur->children = (xmlNodePtr) ent;
|
cur->children = (xmlNodePtr) ent;
|
||||||
|
cur->last = (xmlNodePtr) ent;
|
||||||
}
|
}
|
||||||
return(cur);
|
return(cur);
|
||||||
}
|
}
|
||||||
@ -1662,6 +1686,47 @@ xmlNewDocComment(xmlDocPtr doc, const xmlChar *content) {
|
|||||||
return(cur);
|
return(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlSetTreeDoc:
|
||||||
|
* @tree: the top element
|
||||||
|
* @doc: the document
|
||||||
|
*
|
||||||
|
* update all nodes under the tree to point to the right document
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlSetTreeDoc(xmlNodePtr tree, xmlDocPtr doc) {
|
||||||
|
if (tree == NULL)
|
||||||
|
return;
|
||||||
|
if (tree->type == XML_ENTITY_DECL)
|
||||||
|
return;
|
||||||
|
if (tree->doc != doc) {
|
||||||
|
if (tree->children != NULL)
|
||||||
|
xmlSetListDoc(tree->children, doc);
|
||||||
|
tree->doc = doc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlSetListDoc:
|
||||||
|
* @tree: the first element
|
||||||
|
* @doc: the document
|
||||||
|
*
|
||||||
|
* update all nodes in the list to point to the right document
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlSetListDoc(xmlNodePtr list, xmlDocPtr doc) {
|
||||||
|
xmlNodePtr cur;
|
||||||
|
|
||||||
|
if (list == NULL)
|
||||||
|
return;
|
||||||
|
cur = list;
|
||||||
|
while (cur != NULL) {
|
||||||
|
if (cur->doc != doc)
|
||||||
|
xmlSetTreeDoc(cur, doc);
|
||||||
|
cur = cur->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlNewChild:
|
* xmlNewChild:
|
||||||
@ -1779,7 +1844,8 @@ xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
|
|||||||
xmlNodeSetContent(cur->next, tmp);
|
xmlNodeSetContent(cur->next, tmp);
|
||||||
xmlFree(tmp);
|
xmlFree(tmp);
|
||||||
#else
|
#else
|
||||||
xmlBufferAddHead(cur->next, xmlBufferContent(elem->content),
|
xmlBufferAddHead(cur->next->content,
|
||||||
|
xmlBufferContent(elem->content),
|
||||||
xmlBufferLength(elem->content));
|
xmlBufferLength(elem->content));
|
||||||
#endif
|
#endif
|
||||||
xmlFreeNode(elem);
|
xmlFreeNode(elem);
|
||||||
@ -1787,7 +1853,9 @@ xmlAddNextSibling(xmlNodePtr cur, xmlNodePtr elem) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elem->doc = cur->doc;
|
if (elem->doc != cur->doc) {
|
||||||
|
xmlSetTreeDoc(elem, cur->doc);
|
||||||
|
}
|
||||||
elem->parent = cur->parent;
|
elem->parent = cur->parent;
|
||||||
elem->prev = cur;
|
elem->prev = cur;
|
||||||
elem->next = cur->next;
|
elem->next = cur->next;
|
||||||
@ -1857,7 +1925,9 @@ xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
elem->doc = cur->doc;
|
if (elem->doc != cur->doc) {
|
||||||
|
xmlSetTreeDoc(elem, cur->doc);
|
||||||
|
}
|
||||||
elem->parent = cur->parent;
|
elem->parent = cur->parent;
|
||||||
elem->next = cur;
|
elem->next = cur;
|
||||||
elem->prev = cur->prev;
|
elem->prev = cur->prev;
|
||||||
@ -1926,9 +1996,9 @@ xmlAddSibling(xmlNodePtr cur, xmlNodePtr elem) {
|
|||||||
return(cur);
|
return(cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elem->doc == NULL)
|
if (elem->doc != cur->doc) {
|
||||||
elem->doc = cur->doc; /* the parent may not be linked to a doc ! */
|
xmlSetTreeDoc(elem, cur->doc);
|
||||||
|
}
|
||||||
parent = cur->parent;
|
parent = cur->parent;
|
||||||
elem->prev = cur;
|
elem->prev = cur;
|
||||||
elem->next = NULL;
|
elem->next = NULL;
|
||||||
@ -2011,7 +2081,9 @@ xmlAddChildList(xmlNodePtr parent, xmlNodePtr cur) {
|
|||||||
}
|
}
|
||||||
while (cur->next != NULL) {
|
while (cur->next != NULL) {
|
||||||
cur->parent = parent;
|
cur->parent = parent;
|
||||||
cur->doc = parent->doc; /* the parent may not be linked to a doc ! */
|
if (cur->doc != parent->doc) {
|
||||||
|
xmlSetTreeDoc(cur, parent->doc);
|
||||||
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
cur->parent = parent;
|
cur->parent = parent;
|
||||||
@ -2090,7 +2162,9 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
|
|||||||
* add the new element at the end of the children list.
|
* add the new element at the end of the children list.
|
||||||
*/
|
*/
|
||||||
cur->parent = parent;
|
cur->parent = parent;
|
||||||
cur->doc = parent->doc; /* the parent may not be linked to a doc ! */
|
if (cur->doc != parent->doc) {
|
||||||
|
xmlSetTreeDoc(cur, parent->doc);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle the case where parent->content != NULL, in that case it will
|
* Handle the case where parent->content != NULL, in that case it will
|
||||||
@ -2110,7 +2184,7 @@ xmlAddChild(xmlNodePtr parent, xmlNodePtr cur) {
|
|||||||
if (text->next != NULL)
|
if (text->next != NULL)
|
||||||
text->next->prev = text;
|
text->next->prev = text;
|
||||||
parent->children = text;
|
parent->children = text;
|
||||||
UPDATE_LAST_CHILD(parent)
|
UPDATE_LAST_CHILD_AND_PARENT(parent)
|
||||||
#ifndef XML_USE_BUFFER_CONTENT
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
xmlFree(parent->content);
|
xmlFree(parent->content);
|
||||||
#else
|
#else
|
||||||
@ -2264,6 +2338,9 @@ xmlReplaceNode(xmlNodePtr old, xmlNodePtr cur) {
|
|||||||
xmlUnlinkNode(old);
|
xmlUnlinkNode(old);
|
||||||
return(old);
|
return(old);
|
||||||
}
|
}
|
||||||
|
if (cur == old) {
|
||||||
|
return(old);
|
||||||
|
}
|
||||||
xmlUnlinkNode(cur);
|
xmlUnlinkNode(cur);
|
||||||
cur->doc = old->doc;
|
cur->doc = old->doc;
|
||||||
cur->parent = old->parent;
|
cur->parent = old->parent;
|
||||||
@ -2374,8 +2451,19 @@ xmlCopyProp(xmlNodePtr target, xmlAttrPtr cur) {
|
|||||||
} else
|
} else
|
||||||
ret->ns = NULL;
|
ret->ns = NULL;
|
||||||
|
|
||||||
if (cur->children != NULL)
|
if (cur->children != NULL) {
|
||||||
|
xmlNodePtr tmp;
|
||||||
|
|
||||||
ret->children = xmlCopyNodeList(cur->children);
|
ret->children = xmlCopyNodeList(cur->children);
|
||||||
|
ret->last = NULL;
|
||||||
|
tmp = ret->children;
|
||||||
|
while (tmp != NULL) {
|
||||||
|
tmp->parent = (xmlNodePtr)ret;
|
||||||
|
if (tmp->next == NULL)
|
||||||
|
ret->last = tmp;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2494,7 +2582,7 @@ xmlStaticCopyNode(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent,
|
|||||||
ret->properties = xmlCopyPropList(ret, node->properties);
|
ret->properties = xmlCopyPropList(ret, node->properties);
|
||||||
if (node->children != NULL)
|
if (node->children != NULL)
|
||||||
ret->children = xmlStaticCopyNodeList(node->children, doc, ret);
|
ret->children = xmlStaticCopyNodeList(node->children, doc, ret);
|
||||||
UPDATE_LAST_CHILD(ret)
|
UPDATE_LAST_CHILD_AND_PARENT(ret)
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2633,9 +2721,18 @@ xmlCopyDoc(xmlDocPtr doc, int recursive) {
|
|||||||
ret->intSubset = xmlCopyDtd(doc->intSubset);
|
ret->intSubset = xmlCopyDtd(doc->intSubset);
|
||||||
if (doc->oldNs != NULL)
|
if (doc->oldNs != NULL)
|
||||||
ret->oldNs = xmlCopyNamespaceList(doc->oldNs);
|
ret->oldNs = xmlCopyNamespaceList(doc->oldNs);
|
||||||
if (doc->children != NULL)
|
if (doc->children != NULL) {
|
||||||
|
xmlNodePtr tmp;
|
||||||
ret->children = xmlStaticCopyNodeList(doc->children, ret,
|
ret->children = xmlStaticCopyNodeList(doc->children, ret,
|
||||||
(xmlNodePtr)ret);
|
(xmlNodePtr)ret);
|
||||||
|
ret->last = NULL;
|
||||||
|
tmp = ret->children;
|
||||||
|
while (tmp != NULL) {
|
||||||
|
if (tmp->next == NULL)
|
||||||
|
ret->last = tmp;
|
||||||
|
tmp = tmp->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2692,6 +2789,7 @@ xmlDocSetRootElement(xmlDocPtr doc, xmlNodePtr root) {
|
|||||||
if (old == NULL) {
|
if (old == NULL) {
|
||||||
if (doc->children == NULL) {
|
if (doc->children == NULL) {
|
||||||
doc->children = root;
|
doc->children = root;
|
||||||
|
doc->last = root;
|
||||||
} else {
|
} else {
|
||||||
xmlAddSibling(doc->children, root);
|
xmlAddSibling(doc->children, root);
|
||||||
}
|
}
|
||||||
@ -2732,6 +2830,8 @@ xmlNodeSetLang(xmlNodePtr cur, const xmlChar *lang) {
|
|||||||
#ifdef LIBXML_SGML_ENABLED
|
#ifdef LIBXML_SGML_ENABLED
|
||||||
case XML_SGML_DOCUMENT_NODE:
|
case XML_SGML_DOCUMENT_NODE:
|
||||||
#endif
|
#endif
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
return;
|
return;
|
||||||
case XML_ELEMENT_NODE:
|
case XML_ELEMENT_NODE:
|
||||||
case XML_ATTRIBUTE_NODE:
|
case XML_ATTRIBUTE_NODE:
|
||||||
@ -2792,6 +2892,8 @@ xmlNodeSetSpacePreserve(xmlNodePtr cur, int val) {
|
|||||||
case XML_ENTITY_REF_NODE:
|
case XML_ENTITY_REF_NODE:
|
||||||
case XML_ENTITY_NODE:
|
case XML_ENTITY_NODE:
|
||||||
case XML_NAMESPACE_DECL:
|
case XML_NAMESPACE_DECL:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
#ifdef LIBXML_SGML_ENABLED
|
#ifdef LIBXML_SGML_ENABLED
|
||||||
case XML_SGML_DOCUMENT_NODE:
|
case XML_SGML_DOCUMENT_NODE:
|
||||||
#endif
|
#endif
|
||||||
@ -2863,6 +2965,8 @@ xmlNodeSetName(xmlNodePtr cur, const xmlChar *name) {
|
|||||||
case XML_NOTATION_NODE:
|
case XML_NOTATION_NODE:
|
||||||
case XML_HTML_DOCUMENT_NODE:
|
case XML_HTML_DOCUMENT_NODE:
|
||||||
case XML_NAMESPACE_DECL:
|
case XML_NAMESPACE_DECL:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
#ifdef LIBXML_SGML_ENABLED
|
#ifdef LIBXML_SGML_ENABLED
|
||||||
case XML_SGML_DOCUMENT_NODE:
|
case XML_SGML_DOCUMENT_NODE:
|
||||||
#endif
|
#endif
|
||||||
@ -2911,6 +3015,8 @@ xmlNodeSetBase(xmlNodePtr cur, xmlChar* uri) {
|
|||||||
case XML_ENTITY_REF_NODE:
|
case XML_ENTITY_REF_NODE:
|
||||||
case XML_ENTITY_NODE:
|
case XML_ENTITY_NODE:
|
||||||
case XML_NAMESPACE_DECL:
|
case XML_NAMESPACE_DECL:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
#ifdef LIBXML_SGML_ENABLED
|
#ifdef LIBXML_SGML_ENABLED
|
||||||
case XML_SGML_DOCUMENT_NODE:
|
case XML_SGML_DOCUMENT_NODE:
|
||||||
#endif
|
#endif
|
||||||
@ -2922,6 +3028,34 @@ xmlNodeSetBase(xmlNodePtr cur, xmlChar* uri) {
|
|||||||
xmlSetProp(cur, BAD_CAST "xml:base", uri);
|
xmlSetProp(cur, BAD_CAST "xml:base", uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlDocumentGetBase:
|
||||||
|
* @doc: the document
|
||||||
|
*
|
||||||
|
* Searches for the Document BASE URL. The code should work on both XML
|
||||||
|
* and HTML document.
|
||||||
|
* It returns the base as defined in RFC 2396 section
|
||||||
|
* 5.1.3. Base URI from the Retrieval URI
|
||||||
|
* However it does not return the computed base (5.1.1 and 5.1.2), use
|
||||||
|
* xmlNodeGetBase() for this
|
||||||
|
*
|
||||||
|
* Returns a pointer to the base URL, or NULL if not found
|
||||||
|
* It's up to the caller to free the memory.
|
||||||
|
*/
|
||||||
|
xmlChar *
|
||||||
|
xmlDocumentGetBase(xmlDocPtr doc) {
|
||||||
|
if (doc == NULL)
|
||||||
|
return(NULL);
|
||||||
|
if (doc->type == XML_HTML_DOCUMENT_NODE) {
|
||||||
|
if (doc->URL != NULL)
|
||||||
|
return(xmlStrdup(doc->URL));
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
if (doc->URL != NULL)
|
||||||
|
return(xmlStrdup(doc->URL));
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlNodeGetBase:
|
* xmlNodeGetBase:
|
||||||
* @doc: the document the node pertains to
|
* @doc: the document the node pertains to
|
||||||
@ -2929,6 +3063,12 @@ xmlNodeSetBase(xmlNodePtr cur, xmlChar* uri) {
|
|||||||
*
|
*
|
||||||
* Searches for the BASE URL. The code should work on both XML
|
* Searches for the BASE URL. The code should work on both XML
|
||||||
* and HTML document even if base mechanisms are completely different.
|
* and HTML document even if base mechanisms are completely different.
|
||||||
|
* It returns the base as defined in RFC 2396 sections
|
||||||
|
* 5.1.1. Base URI within Document Content
|
||||||
|
* and
|
||||||
|
* 5.1.2. Base URI from the Encapsulating Entity
|
||||||
|
* However it does not return the document base (5.1.3), use
|
||||||
|
* xmlDocumentGetBase() for this
|
||||||
*
|
*
|
||||||
* Returns a pointer to the base URL, or NULL if not found
|
* Returns a pointer to the base URL, or NULL if not found
|
||||||
* It's up to the caller to free the memory.
|
* It's up to the caller to free the memory.
|
||||||
@ -2943,9 +3083,6 @@ xmlNodeGetBase(xmlDocPtr doc, xmlNodePtr cur) {
|
|||||||
if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
|
if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) {
|
||||||
cur = doc->children;
|
cur = doc->children;
|
||||||
while ((cur != NULL) && (cur->name != NULL)) {
|
while ((cur != NULL) && (cur->name != NULL)) {
|
||||||
if (cur->type == XML_ENTITY_DECL) {
|
|
||||||
/* TODO: we are crossing entity boundaries */
|
|
||||||
}
|
|
||||||
if (cur->type != XML_ELEMENT_NODE) {
|
if (cur->type != XML_ELEMENT_NODE) {
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
continue;
|
continue;
|
||||||
@ -2963,18 +3100,18 @@ xmlNodeGetBase(xmlDocPtr doc, xmlNodePtr cur) {
|
|||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
}
|
}
|
||||||
if ((doc != NULL) && (doc->URL != NULL))
|
|
||||||
return(xmlStrdup(doc->URL));
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
|
if (cur->type == XML_ENTITY_DECL) {
|
||||||
|
xmlEntityPtr ent = (xmlEntityPtr) cur;
|
||||||
|
return(xmlStrdup(ent->URI));
|
||||||
|
}
|
||||||
base = xmlGetProp(cur, BAD_CAST "xml:base");
|
base = xmlGetProp(cur, BAD_CAST "xml:base");
|
||||||
if (base != NULL)
|
if (base != NULL)
|
||||||
return(base);
|
return(base);
|
||||||
cur = cur->parent;
|
cur = cur->parent;
|
||||||
}
|
}
|
||||||
if ((doc != NULL) && (doc->URL != NULL))
|
|
||||||
return(xmlStrdup(doc->URL));
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3026,13 +3163,14 @@ xmlNodeGetContent(xmlNodePtr cur) {
|
|||||||
case XML_DOCUMENT_TYPE_NODE:
|
case XML_DOCUMENT_TYPE_NODE:
|
||||||
case XML_NOTATION_NODE:
|
case XML_NOTATION_NODE:
|
||||||
case XML_DTD_NODE:
|
case XML_DTD_NODE:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
#ifdef LIBXML_SGML_ENABLED
|
#ifdef LIBXML_SGML_ENABLED
|
||||||
case XML_SGML_DOCUMENT_NODE:
|
case XML_SGML_DOCUMENT_NODE:
|
||||||
#endif
|
#endif
|
||||||
return(NULL);
|
return(NULL);
|
||||||
case XML_NAMESPACE_DECL:
|
case XML_NAMESPACE_DECL:
|
||||||
/* TODO !!! */
|
return(xmlStrdup(((xmlNsPtr)cur)->href));
|
||||||
return(NULL);
|
|
||||||
case XML_ELEMENT_DECL:
|
case XML_ELEMENT_DECL:
|
||||||
/* TODO !!! */
|
/* TODO !!! */
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@ -3084,7 +3222,7 @@ xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
|
|||||||
}
|
}
|
||||||
if (cur->children != NULL) xmlFreeNodeList(cur->children);
|
if (cur->children != NULL) xmlFreeNodeList(cur->children);
|
||||||
cur->children = xmlStringGetNodeList(cur->doc, content);
|
cur->children = xmlStringGetNodeList(cur->doc, content);
|
||||||
UPDATE_LAST_CHILD(cur)
|
UPDATE_LAST_CHILD_AND_PARENT(cur)
|
||||||
break;
|
break;
|
||||||
case XML_ATTRIBUTE_NODE:
|
case XML_ATTRIBUTE_NODE:
|
||||||
break;
|
break;
|
||||||
@ -3118,6 +3256,8 @@ xmlNodeSetContent(xmlNodePtr cur, const xmlChar *content) {
|
|||||||
case XML_DOCUMENT_NODE:
|
case XML_DOCUMENT_NODE:
|
||||||
case XML_HTML_DOCUMENT_NODE:
|
case XML_HTML_DOCUMENT_NODE:
|
||||||
case XML_DOCUMENT_TYPE_NODE:
|
case XML_DOCUMENT_TYPE_NODE:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
#ifdef LIBXML_SGML_ENABLED
|
#ifdef LIBXML_SGML_ENABLED
|
||||||
case XML_SGML_DOCUMENT_NODE:
|
case XML_SGML_DOCUMENT_NODE:
|
||||||
#endif
|
#endif
|
||||||
@ -3170,7 +3310,7 @@ xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
|
|||||||
}
|
}
|
||||||
if (cur->children != NULL) xmlFreeNodeList(cur->children);
|
if (cur->children != NULL) xmlFreeNodeList(cur->children);
|
||||||
cur->children = xmlStringLenGetNodeList(cur->doc, content, len);
|
cur->children = xmlStringLenGetNodeList(cur->doc, content, len);
|
||||||
UPDATE_LAST_CHILD(cur)
|
UPDATE_LAST_CHILD_AND_PARENT(cur)
|
||||||
break;
|
break;
|
||||||
case XML_ATTRIBUTE_NODE:
|
case XML_ATTRIBUTE_NODE:
|
||||||
break;
|
break;
|
||||||
@ -3207,6 +3347,8 @@ xmlNodeSetContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
|
|||||||
case XML_HTML_DOCUMENT_NODE:
|
case XML_HTML_DOCUMENT_NODE:
|
||||||
case XML_DOCUMENT_TYPE_NODE:
|
case XML_DOCUMENT_TYPE_NODE:
|
||||||
case XML_NAMESPACE_DECL:
|
case XML_NAMESPACE_DECL:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
#ifdef LIBXML_SGML_ENABLED
|
#ifdef LIBXML_SGML_ENABLED
|
||||||
case XML_SGML_DOCUMENT_NODE:
|
case XML_SGML_DOCUMENT_NODE:
|
||||||
#endif
|
#endif
|
||||||
@ -3256,7 +3398,7 @@ xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
|
|||||||
cur->children = xmlStringGetNodeList(cur->doc,
|
cur->children = xmlStringGetNodeList(cur->doc,
|
||||||
xmlBufferContent(cur->content));
|
xmlBufferContent(cur->content));
|
||||||
#endif
|
#endif
|
||||||
UPDATE_LAST_CHILD(cur)
|
UPDATE_LAST_CHILD_AND_PARENT(cur)
|
||||||
#ifndef XML_USE_BUFFER_CONTENT
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
xmlFree(cur->content);
|
xmlFree(cur->content);
|
||||||
#else
|
#else
|
||||||
@ -3296,6 +3438,8 @@ xmlNodeAddContentLen(xmlNodePtr cur, const xmlChar *content, int len) {
|
|||||||
case XML_HTML_DOCUMENT_NODE:
|
case XML_HTML_DOCUMENT_NODE:
|
||||||
case XML_DOCUMENT_TYPE_NODE:
|
case XML_DOCUMENT_TYPE_NODE:
|
||||||
case XML_NAMESPACE_DECL:
|
case XML_NAMESPACE_DECL:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
#ifdef LIBXML_SGML_ENABLED
|
#ifdef LIBXML_SGML_ENABLED
|
||||||
case XML_SGML_DOCUMENT_NODE:
|
case XML_SGML_DOCUMENT_NODE:
|
||||||
#endif
|
#endif
|
||||||
@ -3944,12 +4088,14 @@ xmlSetProp(xmlNodePtr node, const xmlChar *name, const xmlChar *value) {
|
|||||||
if (prop->children != NULL)
|
if (prop->children != NULL)
|
||||||
xmlFreeNodeList(prop->children);
|
xmlFreeNodeList(prop->children);
|
||||||
prop->children = NULL;
|
prop->children = NULL;
|
||||||
|
prop->last = NULL;
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
xmlChar *buffer;
|
xmlChar *buffer;
|
||||||
xmlNodePtr tmp;
|
xmlNodePtr tmp;
|
||||||
|
|
||||||
buffer = xmlEncodeEntitiesReentrant(node->doc, value);
|
buffer = xmlEncodeEntitiesReentrant(node->doc, value);
|
||||||
prop->children = xmlStringGetNodeList(node->doc, buffer);
|
prop->children = xmlStringGetNodeList(node->doc, buffer);
|
||||||
|
prop->last = NULL;
|
||||||
tmp = prop->children;
|
tmp = prop->children;
|
||||||
while (tmp != NULL) {
|
while (tmp != NULL) {
|
||||||
tmp->parent = (xmlNodePtr) prop;
|
tmp->parent = (xmlNodePtr) prop;
|
||||||
@ -3993,12 +4139,16 @@ xmlNodeIsText(xmlNodePtr node) {
|
|||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xmlIsBlankNode(xmlNodePtr node) {
|
xmlIsBlankNode(xmlNodePtr node) {
|
||||||
xmlChar *cur;
|
const xmlChar *cur;
|
||||||
if (node == NULL) return(0);
|
if (node == NULL) return(0);
|
||||||
|
|
||||||
if (node->type != XML_TEXT_NODE) return(0);
|
if (node->type != XML_TEXT_NODE) return(0);
|
||||||
if (node->content == NULL) return(1);
|
if (node->content == NULL) return(1);
|
||||||
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
cur = node->content;
|
cur = node->content;
|
||||||
|
#else
|
||||||
|
cur = xmlBufferContent(node->content);
|
||||||
|
#endif
|
||||||
while (*cur != 0) {
|
while (*cur != 0) {
|
||||||
if (!IS_BLANK(*cur)) return(0);
|
if (!IS_BLANK(*cur)) return(0);
|
||||||
cur++;
|
cur++;
|
||||||
@ -4749,6 +4899,10 @@ xmlNodeDump(xmlBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur, int level,
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (cur->type == XML_XINCLUDE_START)
|
||||||
|
return;
|
||||||
|
if (cur->type == XML_XINCLUDE_END)
|
||||||
|
return;
|
||||||
if (cur->type == XML_DTD_NODE) {
|
if (cur->type == XML_DTD_NODE) {
|
||||||
xmlDtdDump(buf, (xmlDtdPtr) cur);
|
xmlDtdDump(buf, (xmlDtdPtr) cur);
|
||||||
return;
|
return;
|
||||||
@ -5201,6 +5355,10 @@ xmlNodeDumpOutput(xmlOutputBufferPtr buf, xmlDocPtr doc, xmlNodePtr cur,
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (cur->type == XML_XINCLUDE_START)
|
||||||
|
return;
|
||||||
|
if (cur->type == XML_XINCLUDE_END)
|
||||||
|
return;
|
||||||
if (cur->type == XML_DTD_NODE) {
|
if (cur->type == XML_DTD_NODE) {
|
||||||
xmlDtdDumpOutput(buf, (xmlDtdPtr) cur, encoding);
|
xmlDtdDumpOutput(buf, (xmlDtdPtr) cur, encoding);
|
||||||
return;
|
return;
|
||||||
|
6
tree.h
6
tree.h
@ -41,9 +41,11 @@ typedef enum {
|
|||||||
XML_ELEMENT_DECL= 15,
|
XML_ELEMENT_DECL= 15,
|
||||||
XML_ATTRIBUTE_DECL= 16,
|
XML_ATTRIBUTE_DECL= 16,
|
||||||
XML_ENTITY_DECL= 17,
|
XML_ENTITY_DECL= 17,
|
||||||
XML_NAMESPACE_DECL= 18
|
XML_NAMESPACE_DECL= 18,
|
||||||
|
XML_XINCLUDE_START= 19,
|
||||||
|
XML_XINCLUDE_END= 20
|
||||||
#ifdef LIBXML_SGML_ENABLED
|
#ifdef LIBXML_SGML_ENABLED
|
||||||
,XML_SGML_DOCUMENT_NODE= 19
|
,XML_SGML_DOCUMENT_NODE= 21
|
||||||
#endif
|
#endif
|
||||||
} xmlElementType;
|
} xmlElementType;
|
||||||
|
|
||||||
|
353
uri.c
353
uri.c
@ -22,6 +22,13 @@
|
|||||||
#include <libxml/uri.h>
|
#include <libxml/uri.h>
|
||||||
#include <libxml/xmlerror.h>
|
#include <libxml/xmlerror.h>
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Macros to differenciate various character type *
|
||||||
|
* directly extracted from RFC 2396 *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* alpha = lowalpha | upalpha
|
* alpha = lowalpha | upalpha
|
||||||
*/
|
*/
|
||||||
@ -169,6 +176,12 @@
|
|||||||
* path = [ abs_path | opaque_part ]
|
* path = [ abs_path | opaque_part ]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Generic URI structure functions *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlCreateURI:
|
* xmlCreateURI:
|
||||||
*
|
*
|
||||||
@ -587,6 +600,143 @@ xmlFreeURI(xmlURIPtr uri) {
|
|||||||
xmlFree(uri);
|
xmlFree(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Helper functions *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlNormalizeURIPath:
|
||||||
|
* @path: pointer to the path string
|
||||||
|
*
|
||||||
|
* applies the 5 normalization steps to a path string
|
||||||
|
* Normalization occurs directly on the string, no new allocation is done
|
||||||
|
*
|
||||||
|
* Returns 0 or an error code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlNormalizeURIPath(char *path) {
|
||||||
|
int cur, out;
|
||||||
|
|
||||||
|
if (path == NULL)
|
||||||
|
return(-1);
|
||||||
|
cur = 0;
|
||||||
|
out = 0;
|
||||||
|
while ((path[cur] != 0) && (path[cur] != '/')) cur++;
|
||||||
|
if (path[cur] == 0)
|
||||||
|
return(0);
|
||||||
|
|
||||||
|
/* we are positionned at the beginning of the first segment */
|
||||||
|
cur++;
|
||||||
|
out = cur;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Analyze each segment in sequence.
|
||||||
|
*/
|
||||||
|
while (path[cur] != 0) {
|
||||||
|
/*
|
||||||
|
* c) All occurrences of "./", where "." is a complete path segment,
|
||||||
|
* are removed from the buffer string.
|
||||||
|
*/
|
||||||
|
if ((path[cur] == '.') && (path[cur + 1] == '/')) {
|
||||||
|
cur += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* d) If the buffer string ends with "." as a complete path segment,
|
||||||
|
* that "." is removed.
|
||||||
|
*/
|
||||||
|
if ((path[cur] == '.') && (path[cur + 1] == 0)) {
|
||||||
|
path[out] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read the segment */
|
||||||
|
while ((path[cur] != 0) && (path[cur] != '/')) {
|
||||||
|
path[out++] = path[cur++];
|
||||||
|
}
|
||||||
|
path[out++] = path[cur];
|
||||||
|
if (path[cur] != 0) {
|
||||||
|
cur++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cur = 0;
|
||||||
|
out = 0;
|
||||||
|
while ((path[cur] != 0) && (path[cur] != '/')) cur++;
|
||||||
|
if (path[cur] == 0)
|
||||||
|
return(0);
|
||||||
|
/* we are positionned at the beginning of the first segment */
|
||||||
|
cur++;
|
||||||
|
out = cur;
|
||||||
|
/*
|
||||||
|
* Analyze each segment in sequence.
|
||||||
|
*/
|
||||||
|
while (path[cur] != 0) {
|
||||||
|
/*
|
||||||
|
* e) All occurrences of "<segment>/../", where <segment> is a
|
||||||
|
* complete path segment not equal to "..", are removed from the
|
||||||
|
* buffer string. Removal of these path segments is performed
|
||||||
|
* iteratively, removing the leftmost matching pattern on each
|
||||||
|
* iteration, until no matching pattern remains.
|
||||||
|
*/
|
||||||
|
if ((cur > 1) && (out > 1) &&
|
||||||
|
(path[cur] == '/') && (path[cur + 1] == '.') &&
|
||||||
|
(path[cur + 2] == '.') && (path[cur + 3] == '/') &&
|
||||||
|
((path[out] != '.') || (path[out - 1] != '.') ||
|
||||||
|
(path[out - 2] != '/'))) {
|
||||||
|
cur += 3;
|
||||||
|
out --;
|
||||||
|
while ((out > 0) && (path[out] != '/')) { out --; }
|
||||||
|
path[out] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* f) If the buffer string ends with "<segment>/..", where <segment>
|
||||||
|
* is a complete path segment not equal to "..", that
|
||||||
|
* "<segment>/.." is removed.
|
||||||
|
*/
|
||||||
|
if ((path[cur] == '/') && (path[cur + 1] == '.') &&
|
||||||
|
(path[cur + 2] == '.') && (path[cur + 3] == 0) &&
|
||||||
|
((path[out] != '.') || (path[out - 1] != '.') ||
|
||||||
|
(path[out - 2] != '/'))) {
|
||||||
|
cur += 4;
|
||||||
|
out --;
|
||||||
|
while ((out > 0) && (path[out - 1] != '/')) { out --; }
|
||||||
|
path[out] = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
path[out++] = path[cur++]; /* / or 0 */
|
||||||
|
}
|
||||||
|
path[out] = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* g) If the resulting buffer string still begins with one or more
|
||||||
|
* complete path segments of "..", then the reference is
|
||||||
|
* considered to be in error. Implementations may handle this
|
||||||
|
* error by retaining these components in the resolved path (i.e.,
|
||||||
|
* treating them as part of the final URI), by removing them from
|
||||||
|
* the resolved path (i.e., discarding relative levels above the
|
||||||
|
* root), or by avoiding traversal of the reference.
|
||||||
|
*
|
||||||
|
* We discard them from the final path.
|
||||||
|
*/
|
||||||
|
cur = 0;
|
||||||
|
while ((path[cur] == '/') && (path[cur + 1] == '.') &&
|
||||||
|
(path[cur + 2] == '.'))
|
||||||
|
cur += 3;
|
||||||
|
if (cur != 0) {
|
||||||
|
out = 0;
|
||||||
|
while (path[cur] != 0) path[out++] = path[cur++];
|
||||||
|
path[out] = 0;
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlURIUnescapeString:
|
* xmlURIUnescapeString:
|
||||||
* @str: the string to unescape
|
* @str: the string to unescape
|
||||||
@ -647,6 +797,74 @@ xmlURIUnescapeString(const char *str, int len, char *target) {
|
|||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlURIEscape:
|
||||||
|
* @str: the string of the URI to escape
|
||||||
|
*
|
||||||
|
* Escaping routine, does not do validity checks !
|
||||||
|
* It will try to escape the chars needing this, but this is heuristic
|
||||||
|
* based it's impossible to be sure.
|
||||||
|
*
|
||||||
|
* Returns an copy of the string, but escaped
|
||||||
|
*/
|
||||||
|
xmlChar *
|
||||||
|
xmlURIEscape(const xmlChar *str) {
|
||||||
|
xmlChar *ret;
|
||||||
|
const xmlChar *in;
|
||||||
|
unsigned int len, out;
|
||||||
|
|
||||||
|
if (str == NULL)
|
||||||
|
return(NULL);
|
||||||
|
len = xmlStrlen(str);
|
||||||
|
if (len <= 0) return(NULL);
|
||||||
|
|
||||||
|
len += 20;
|
||||||
|
ret = (xmlChar *) xmlMalloc(len);
|
||||||
|
if (ret == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"xmlURIEscape: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
in = (const xmlChar *) str;
|
||||||
|
out = 0;
|
||||||
|
while(*in != 0) {
|
||||||
|
if (len - out <= 3) {
|
||||||
|
len += 20;
|
||||||
|
ret = (xmlChar *) xmlRealloc(ret, len);
|
||||||
|
if (ret == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"xmlURIEscape: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((!IS_UNRESERVED(*in)) && (*in != ':') && (*in != '/') &&
|
||||||
|
(*in != '?') && (*in != '#')) {
|
||||||
|
unsigned char val;
|
||||||
|
ret[out++] = '%';
|
||||||
|
val = *in >> 4;
|
||||||
|
if (val <= 9)
|
||||||
|
ret[out++] = '0' + val;
|
||||||
|
else
|
||||||
|
ret[out++] = 'A' + val - 0xA;
|
||||||
|
val = *in & 0xF;
|
||||||
|
if (val <= 9)
|
||||||
|
ret[out++] = '0' + val;
|
||||||
|
else
|
||||||
|
ret[out++] = 'A' + val - 0xA;
|
||||||
|
in++;
|
||||||
|
} else {
|
||||||
|
ret[out++] = *in++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret[out] = 0;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* Escaped URI parsing *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlParseURIFragment:
|
* xmlParseURIFragment:
|
||||||
@ -1284,136 +1502,11 @@ xmlParseURI(const char *str) {
|
|||||||
return(uri);
|
return(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/************************************************************************
|
||||||
* xmlNormalizeURIPath:
|
* *
|
||||||
* @path: pointer to the path string
|
* Public functions *
|
||||||
*
|
* *
|
||||||
* applies the 5 normalization steps to a path string
|
************************************************************************/
|
||||||
* Normalization occurs directly on the string, no new allocation is done
|
|
||||||
*
|
|
||||||
* Returns 0 or an error code
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
xmlNormalizeURIPath(char *path) {
|
|
||||||
int cur, out;
|
|
||||||
|
|
||||||
if (path == NULL)
|
|
||||||
return(-1);
|
|
||||||
cur = 0;
|
|
||||||
out = 0;
|
|
||||||
while ((path[cur] != 0) && (path[cur] != '/')) cur++;
|
|
||||||
if (path[cur] == 0)
|
|
||||||
return(0);
|
|
||||||
|
|
||||||
/* we are positionned at the beginning of the first segment */
|
|
||||||
cur++;
|
|
||||||
out = cur;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Analyze each segment in sequence.
|
|
||||||
*/
|
|
||||||
while (path[cur] != 0) {
|
|
||||||
/*
|
|
||||||
* c) All occurrences of "./", where "." is a complete path segment,
|
|
||||||
* are removed from the buffer string.
|
|
||||||
*/
|
|
||||||
if ((path[cur] == '.') && (path[cur + 1] == '/')) {
|
|
||||||
cur += 2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* d) If the buffer string ends with "." as a complete path segment,
|
|
||||||
* that "." is removed.
|
|
||||||
*/
|
|
||||||
if ((path[cur] == '.') && (path[cur + 1] == 0)) {
|
|
||||||
path[out] = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read the segment */
|
|
||||||
while ((path[cur] != 0) && (path[cur] != '/')) {
|
|
||||||
path[out++] = path[cur++];
|
|
||||||
}
|
|
||||||
path[out++] = path[cur];
|
|
||||||
if (path[cur] != 0) {
|
|
||||||
cur++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = 0;
|
|
||||||
out = 0;
|
|
||||||
while ((path[cur] != 0) && (path[cur] != '/')) cur++;
|
|
||||||
if (path[cur] == 0)
|
|
||||||
return(0);
|
|
||||||
/* we are positionned at the beginning of the first segment */
|
|
||||||
cur++;
|
|
||||||
out = cur;
|
|
||||||
/*
|
|
||||||
* Analyze each segment in sequence.
|
|
||||||
*/
|
|
||||||
while (path[cur] != 0) {
|
|
||||||
/*
|
|
||||||
* e) All occurrences of "<segment>/../", where <segment> is a
|
|
||||||
* complete path segment not equal to "..", are removed from the
|
|
||||||
* buffer string. Removal of these path segments is performed
|
|
||||||
* iteratively, removing the leftmost matching pattern on each
|
|
||||||
* iteration, until no matching pattern remains.
|
|
||||||
*/
|
|
||||||
if ((cur > 1) && (out > 1) &&
|
|
||||||
(path[cur] == '/') && (path[cur + 1] == '.') &&
|
|
||||||
(path[cur + 2] == '.') && (path[cur + 3] == '/') &&
|
|
||||||
((path[out] != '.') || (path[out - 1] != '.') ||
|
|
||||||
(path[out - 2] != '/'))) {
|
|
||||||
cur += 3;
|
|
||||||
out --;
|
|
||||||
while ((out > 0) && (path[out] != '/')) { out --; }
|
|
||||||
path[out] = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* f) If the buffer string ends with "<segment>/..", where <segment>
|
|
||||||
* is a complete path segment not equal to "..", that
|
|
||||||
* "<segment>/.." is removed.
|
|
||||||
*/
|
|
||||||
if ((path[cur] == '/') && (path[cur + 1] == '.') &&
|
|
||||||
(path[cur + 2] == '.') && (path[cur + 3] == 0) &&
|
|
||||||
((path[out] != '.') || (path[out - 1] != '.') ||
|
|
||||||
(path[out - 2] != '/'))) {
|
|
||||||
cur += 4;
|
|
||||||
out --;
|
|
||||||
while ((out > 0) && (path[out - 1] != '/')) { out --; }
|
|
||||||
path[out] = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
path[out++] = path[cur++]; /* / or 0 */
|
|
||||||
}
|
|
||||||
path[out] = 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* g) If the resulting buffer string still begins with one or more
|
|
||||||
* complete path segments of "..", then the reference is
|
|
||||||
* considered to be in error. Implementations may handle this
|
|
||||||
* error by retaining these components in the resolved path (i.e.,
|
|
||||||
* treating them as part of the final URI), by removing them from
|
|
||||||
* the resolved path (i.e., discarding relative levels above the
|
|
||||||
* root), or by avoiding traversal of the reference.
|
|
||||||
*
|
|
||||||
* We discard them from the final path.
|
|
||||||
*/
|
|
||||||
cur = 0;
|
|
||||||
while ((path[cur] == '/') && (path[cur + 1] == '.') &&
|
|
||||||
(path[cur + 2] == '.'))
|
|
||||||
cur += 3;
|
|
||||||
if (cur != 0) {
|
|
||||||
out = 0;
|
|
||||||
while (path[cur] != 0) path[out++] = path[cur++];
|
|
||||||
path[out] = 0;
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* xmlBuildURI:
|
* xmlBuildURI:
|
||||||
|
1
uri.h
1
uri.h
@ -52,6 +52,7 @@ char * xmlURIUnescapeString (const char *str,
|
|||||||
int len,
|
int len,
|
||||||
char *target);
|
char *target);
|
||||||
int xmlNormalizeURIPath (char *path);
|
int xmlNormalizeURIPath (char *path);
|
||||||
|
xmlChar * xmlURIEscape (const xmlChar *str);
|
||||||
void xmlFreeURI (xmlURIPtr uri);
|
void xmlFreeURI (xmlURIPtr uri);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
3
valid.c
3
valid.c
@ -3212,6 +3212,7 @@ xmlSprintfElementChilds(char *buf, xmlNodePtr node, int glob) {
|
|||||||
case XML_DOCUMENT_TYPE_NODE:
|
case XML_DOCUMENT_TYPE_NODE:
|
||||||
case XML_DOCUMENT_FRAG_NODE:
|
case XML_DOCUMENT_FRAG_NODE:
|
||||||
case XML_NOTATION_NODE:
|
case XML_NOTATION_NODE:
|
||||||
|
case XML_NAMESPACE_DECL:
|
||||||
strcat(buf, "???");
|
strcat(buf, "???");
|
||||||
if (cur->next != NULL)
|
if (cur->next != NULL)
|
||||||
strcat(buf, " ");
|
strcat(buf, " ");
|
||||||
@ -3223,6 +3224,8 @@ xmlSprintfElementChilds(char *buf, xmlNodePtr node, int glob) {
|
|||||||
case XML_ELEMENT_DECL:
|
case XML_ELEMENT_DECL:
|
||||||
case XML_ATTRIBUTE_DECL:
|
case XML_ATTRIBUTE_DECL:
|
||||||
case XML_ENTITY_DECL:
|
case XML_ENTITY_DECL:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cur = cur->next;
|
cur = cur->next;
|
||||||
|
737
xinclude.c
Normal file
737
xinclude.c
Normal file
@ -0,0 +1,737 @@
|
|||||||
|
/*
|
||||||
|
* xinclude.c : Code to implement XInclude processing
|
||||||
|
*
|
||||||
|
* World Wide Web Consortium Working Draft 26 October 2000
|
||||||
|
* http://www.w3.org/TR/2000/WD-xinclude-20001026
|
||||||
|
*
|
||||||
|
* See Copyright for the status of this software.
|
||||||
|
*
|
||||||
|
* Daniel.Veillard@w3.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: compute XPointers nodesets
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "win32config.h"
|
||||||
|
#else
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <libxml/xmlmemory.h>
|
||||||
|
#include <libxml/tree.h>
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
#include <libxml/uri.h>
|
||||||
|
#include <libxml/xpointer.h>
|
||||||
|
#include <libxml/parserInternals.h>
|
||||||
|
#ifdef LIBXML_DEBUG_ENABLED
|
||||||
|
#include <libxml/debugXML.h>
|
||||||
|
#endif
|
||||||
|
#include <libxml/xmlerror.h>
|
||||||
|
|
||||||
|
#ifdef LIBXML_XINCLUDE_ENABLED
|
||||||
|
#include <libxml/xinclude.h>
|
||||||
|
|
||||||
|
#define XINCLUDE_NS (const xmlChar *) "http://www.w3.org/1999/XML/xinclude"
|
||||||
|
#define XINCLUDE_NODE (const xmlChar *) "include"
|
||||||
|
#define XINCLUDE_HREF (const xmlChar *) "href"
|
||||||
|
#define XINCLUDE_PARSE (const xmlChar *) "parse"
|
||||||
|
#define XINCLUDE_PARSE_XML (const xmlChar *) "xml"
|
||||||
|
#define XINCLUDE_PARSE_TEXT (const xmlChar *) "text"
|
||||||
|
|
||||||
|
/* #define DEBUG_XINCLUDE */
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* XInclude contexts handling *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An XInclude context
|
||||||
|
*/
|
||||||
|
typedef xmlChar *URL;
|
||||||
|
typedef struct _xmlXIncludeCtxt xmlXIncludeCtxt;
|
||||||
|
typedef xmlXIncludeCtxt *xmlXIncludeCtxtPtr;
|
||||||
|
struct _xmlXIncludeCtxt {
|
||||||
|
xmlDocPtr doc; /* the source document */
|
||||||
|
int incNr; /* number of includes */
|
||||||
|
int incMax; /* size of includes tab */
|
||||||
|
xmlNodePtr *incTab; /* array of include nodes */
|
||||||
|
xmlNodePtr *repTab; /* array of replacement node lists */
|
||||||
|
int docNr; /* number of parsed documents */
|
||||||
|
int docMax; /* size of parsed documents tab */
|
||||||
|
xmlDocPtr *docTab; /* array of parsed documents */
|
||||||
|
URL *urlTab; /* array of parsed documents URLs */
|
||||||
|
int txtNr; /* number of unparsed documents */
|
||||||
|
int txtMax; /* size of unparsed documents tab */
|
||||||
|
xmlNodePtr *txtTab; /* array of unparsed text nodes */
|
||||||
|
URL *txturlTab; /* array of unparsed txtuments URLs */
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeAddNode:
|
||||||
|
* @ctxt: the XInclude context
|
||||||
|
* @node: the new node
|
||||||
|
*
|
||||||
|
* Add a new node to process to an XInclude context
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlXIncludeAddNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
|
||||||
|
if (ctxt->incMax == 0) {
|
||||||
|
ctxt->incMax = 4;
|
||||||
|
ctxt->incTab = (xmlNodePtr *) xmlMalloc(ctxt->incMax *
|
||||||
|
sizeof(ctxt->incTab[0]));
|
||||||
|
if (ctxt->incTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"malloc failed !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctxt->repTab = (xmlNodePtr *) xmlMalloc(ctxt->incMax *
|
||||||
|
sizeof(ctxt->repTab[0]));
|
||||||
|
if (ctxt->repTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"malloc failed !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ctxt->incNr >= ctxt->incMax) {
|
||||||
|
ctxt->incMax *= 2;
|
||||||
|
ctxt->incTab = (xmlNodePtr *) xmlRealloc(ctxt->incTab,
|
||||||
|
ctxt->incMax * sizeof(ctxt->incTab[0]));
|
||||||
|
if (ctxt->incTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"realloc failed !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctxt->repTab = (xmlNodePtr *) xmlRealloc(ctxt->repTab,
|
||||||
|
ctxt->incMax * sizeof(ctxt->repTab[0]));
|
||||||
|
if (ctxt->repTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"realloc failed !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctxt->incTab[ctxt->incNr] = node;
|
||||||
|
ctxt->repTab[ctxt->incNr] = NULL;
|
||||||
|
ctxt->incNr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeAddDoc:
|
||||||
|
* @ctxt: the XInclude context
|
||||||
|
* @doc: the new document
|
||||||
|
* @url: the associated URL
|
||||||
|
*
|
||||||
|
* Add a new document to the list
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlXIncludeAddDoc(xmlXIncludeCtxtPtr ctxt, xmlDocPtr doc, const URL url) {
|
||||||
|
if (ctxt->docMax == 0) {
|
||||||
|
ctxt->docMax = 4;
|
||||||
|
ctxt->docTab = (xmlDocPtr *) xmlMalloc(ctxt->docMax *
|
||||||
|
sizeof(ctxt->docTab[0]));
|
||||||
|
if (ctxt->docTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"malloc failed !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctxt->urlTab = (URL *) xmlMalloc(ctxt->docMax *
|
||||||
|
sizeof(ctxt->urlTab[0]));
|
||||||
|
if (ctxt->urlTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"malloc failed !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ctxt->docNr >= ctxt->docMax) {
|
||||||
|
ctxt->docMax *= 2;
|
||||||
|
ctxt->docTab = (xmlDocPtr *) xmlRealloc(ctxt->docTab,
|
||||||
|
ctxt->docMax * sizeof(ctxt->docTab[0]));
|
||||||
|
if (ctxt->docTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"realloc failed !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctxt->urlTab = (URL *) xmlRealloc(ctxt->urlTab,
|
||||||
|
ctxt->docMax * sizeof(ctxt->urlTab[0]));
|
||||||
|
if (ctxt->urlTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"realloc failed !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctxt->docTab[ctxt->docNr] = doc;
|
||||||
|
ctxt->urlTab[ctxt->docNr] = xmlStrdup(url);
|
||||||
|
ctxt->docNr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeAddTxt:
|
||||||
|
* @ctxt: the XInclude context
|
||||||
|
* @txt: the new text node
|
||||||
|
* @url: the associated URL
|
||||||
|
*
|
||||||
|
* Add a new txtument to the list
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlXIncludeAddTxt(xmlXIncludeCtxtPtr ctxt, xmlNodePtr txt, const URL url) {
|
||||||
|
if (ctxt->txtMax == 0) {
|
||||||
|
ctxt->txtMax = 4;
|
||||||
|
ctxt->txtTab = (xmlNodePtr *) xmlMalloc(ctxt->txtMax *
|
||||||
|
sizeof(ctxt->txtTab[0]));
|
||||||
|
if (ctxt->txtTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"malloc failed !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctxt->txturlTab = (URL *) xmlMalloc(ctxt->txtMax *
|
||||||
|
sizeof(ctxt->txturlTab[0]));
|
||||||
|
if (ctxt->txturlTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"malloc failed !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ctxt->txtNr >= ctxt->txtMax) {
|
||||||
|
ctxt->txtMax *= 2;
|
||||||
|
ctxt->txtTab = (xmlNodePtr *) xmlRealloc(ctxt->txtTab,
|
||||||
|
ctxt->txtMax * sizeof(ctxt->txtTab[0]));
|
||||||
|
if (ctxt->txtTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"realloc failed !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctxt->txturlTab = (URL *) xmlRealloc(ctxt->txturlTab,
|
||||||
|
ctxt->txtMax * sizeof(ctxt->urlTab[0]));
|
||||||
|
if (ctxt->txturlTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"realloc failed !\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctxt->txtTab[ctxt->txtNr] = txt;
|
||||||
|
ctxt->txturlTab[ctxt->txtNr] = xmlStrdup(url);
|
||||||
|
ctxt->txtNr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeNewContext:
|
||||||
|
* @doc: an XML Document
|
||||||
|
*
|
||||||
|
* Creates a new XInclude context
|
||||||
|
*
|
||||||
|
* Returns the new set
|
||||||
|
*/
|
||||||
|
xmlXIncludeCtxtPtr
|
||||||
|
xmlXIncludeNewContext(xmlDocPtr doc) {
|
||||||
|
xmlXIncludeCtxtPtr ret;
|
||||||
|
|
||||||
|
if (doc == NULL)
|
||||||
|
return(NULL);
|
||||||
|
ret = (xmlXIncludeCtxtPtr) xmlMalloc(sizeof(xmlXIncludeCtxt));
|
||||||
|
if (ret == NULL)
|
||||||
|
return(NULL);
|
||||||
|
memset(ret, 0, sizeof(xmlXIncludeCtxt));
|
||||||
|
ret->doc = doc;
|
||||||
|
ret->incNr = 0;
|
||||||
|
ret->incMax = 0;
|
||||||
|
ret->incTab = NULL;
|
||||||
|
ret->repTab = NULL;
|
||||||
|
ret->docNr = 0;
|
||||||
|
ret->docMax = 0;
|
||||||
|
ret->docTab = NULL;
|
||||||
|
ret->urlTab = NULL;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeFreeContext:
|
||||||
|
* @ctxt: the XInclude context
|
||||||
|
*
|
||||||
|
* Free an XInclude context
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlXIncludeFreeContext(xmlXIncludeCtxtPtr ctxt) {
|
||||||
|
if (ctxt == NULL)
|
||||||
|
return;
|
||||||
|
if (ctxt->incTab != NULL)
|
||||||
|
xmlFree(ctxt->incTab);
|
||||||
|
if (ctxt->repTab != NULL)
|
||||||
|
xmlFree(ctxt->repTab);
|
||||||
|
memset(ctxt, 0xeb, sizeof(xmlXIncludeCtxt));
|
||||||
|
xmlFree(ctxt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* XInclude I/O handling *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeLoadDoc:
|
||||||
|
* @ctxt: the XInclude context
|
||||||
|
* @url: the associated URL
|
||||||
|
* @nr: the xinclude node number
|
||||||
|
*
|
||||||
|
* Load the document, and store the result in the XInclude context
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlXIncludeLoadDoc(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
|
||||||
|
xmlDocPtr doc;
|
||||||
|
xmlURIPtr uri;
|
||||||
|
xmlChar *URL;
|
||||||
|
int i;
|
||||||
|
/*
|
||||||
|
* Check the URL and remove any fragment identifier
|
||||||
|
*/
|
||||||
|
uri = xmlParseURI((const char *)url);
|
||||||
|
if (uri == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"XInclude: invalid value URI %s\n", url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (uri->fragment != NULL) {
|
||||||
|
xmlFree(uri->fragment);
|
||||||
|
uri->fragment = NULL; /* TODO: kkep it for later processing */
|
||||||
|
}
|
||||||
|
URL = xmlSaveUri(uri);
|
||||||
|
xmlFreeURI(uri);
|
||||||
|
if (URL == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"XInclude: invalid value URI %s\n", url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handling of references to the local document are done
|
||||||
|
* directly through ctxt->doc.
|
||||||
|
*/
|
||||||
|
if (URL[0] == 0) {
|
||||||
|
xmlFree(URL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevent reloading twice the document.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < ctxt->docNr; i++) {
|
||||||
|
if (xmlStrEqual(URL, ctxt->urlTab[i])) {
|
||||||
|
doc = ctxt->docTab[i];
|
||||||
|
goto loaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Load it.
|
||||||
|
*/
|
||||||
|
doc = xmlParseFile((const char *)URL);
|
||||||
|
if (doc == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"XInclude: could not load %s\n", URL);
|
||||||
|
xmlFree(URL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
xmlXIncludeAddDoc(ctxt, doc, URL);
|
||||||
|
|
||||||
|
loaded:
|
||||||
|
/*
|
||||||
|
* Add the top children list as the replacement copy.
|
||||||
|
*/
|
||||||
|
ctxt->repTab[nr] = xmlCopyNodeList(doc->children);
|
||||||
|
xmlFree(URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeLoadTxt:
|
||||||
|
* @ctxt: the XInclude context
|
||||||
|
* @url: the associated URL
|
||||||
|
* @nr: the xinclude node number
|
||||||
|
*
|
||||||
|
* Load the content, and store the result in the XInclude context
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
xmlXIncludeLoadTxt(xmlXIncludeCtxtPtr ctxt, const xmlChar *url, int nr) {
|
||||||
|
xmlParserInputBufferPtr buf;
|
||||||
|
xmlNodePtr node;
|
||||||
|
xmlURIPtr uri;
|
||||||
|
xmlChar *URL;
|
||||||
|
int i;
|
||||||
|
/*
|
||||||
|
* Check the URL and remove any fragment identifier
|
||||||
|
*/
|
||||||
|
uri = xmlParseURI((const char *)url);
|
||||||
|
if (uri == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"XInclude: invalid value URI %s\n", url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (uri->fragment != NULL) {
|
||||||
|
xmlFreeURI(uri);
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"XInclude: fragment identifier forbidden for text\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
URL = xmlSaveUri(uri);
|
||||||
|
xmlFreeURI(uri);
|
||||||
|
if (URL == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"XInclude: invalid value URI %s\n", url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handling of references to the local document are done
|
||||||
|
* directly through ctxt->doc.
|
||||||
|
*/
|
||||||
|
if (URL[0] == 0) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"XInclude: text serialization of document not available\n");
|
||||||
|
xmlFree(URL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prevent reloading twice the document.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < ctxt->txtNr; i++) {
|
||||||
|
if (xmlStrEqual(URL, ctxt->txturlTab[i])) {
|
||||||
|
node = xmlCopyNode(ctxt->txtTab[i], 1);
|
||||||
|
goto loaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Load it.
|
||||||
|
* Issue 62: how to detect the encoding
|
||||||
|
*/
|
||||||
|
buf = xmlParserInputBufferCreateFilename((const char *)URL, 0);
|
||||||
|
if (buf == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"XInclude: could not load %s\n", URL);
|
||||||
|
xmlFree(URL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
node = xmlNewText(NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Scan all chars from the resource and add the to the node
|
||||||
|
*/
|
||||||
|
while (xmlParserInputBufferRead(buf, 128) > 0) {
|
||||||
|
int len;
|
||||||
|
const xmlChar *content;
|
||||||
|
|
||||||
|
content = xmlBufferContent(buf->buffer);
|
||||||
|
len = xmlBufferLength(buf->buffer);
|
||||||
|
for (i = 0;i < len; i++) {
|
||||||
|
/*
|
||||||
|
* TODO: if the encoding issue is solved, scan UTF8 chars instead
|
||||||
|
*/
|
||||||
|
if (!IS_CHAR(content[i])) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"XInclude: %s contains invalid char %d\n", URL, content[i]);
|
||||||
|
} else {
|
||||||
|
xmlNodeAddContentLen(node, &content[i], 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xmlBufferShrink(buf->buffer, len);
|
||||||
|
}
|
||||||
|
xmlFreeParserInputBuffer(buf);
|
||||||
|
xmlXIncludeAddTxt(ctxt, node, URL);
|
||||||
|
|
||||||
|
loaded:
|
||||||
|
/*
|
||||||
|
* Add the element as the replacement copy.
|
||||||
|
*/
|
||||||
|
ctxt->repTab[nr] = node;
|
||||||
|
xmlFree(URL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* *
|
||||||
|
* XInclude Processing *
|
||||||
|
* *
|
||||||
|
************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludePreProcessNode:
|
||||||
|
* @ctxt: an XInclude context
|
||||||
|
* @node: an XInclude node
|
||||||
|
*
|
||||||
|
* Implement the infoset replacement lookup on the XML element @node
|
||||||
|
*
|
||||||
|
* Returns the result list or NULL in case of error
|
||||||
|
*/
|
||||||
|
xmlNodePtr
|
||||||
|
xmlXIncludePreProcessNode(xmlXIncludeCtxtPtr ctxt, xmlNodePtr node) {
|
||||||
|
xmlXIncludeAddNode(ctxt, node);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeLoadNode:
|
||||||
|
* @ctxt: an XInclude context
|
||||||
|
* @nr: the node number
|
||||||
|
*
|
||||||
|
* Find and load the infoset replacement for the given node.
|
||||||
|
*
|
||||||
|
* Returns 0 if substition succeeded, -1 if some processing failed
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlXIncludeLoadNode(xmlXIncludeCtxtPtr ctxt, int nr) {
|
||||||
|
xmlNodePtr cur;
|
||||||
|
xmlChar *href;
|
||||||
|
xmlChar *parse;
|
||||||
|
xmlChar *base;
|
||||||
|
xmlChar *URI;
|
||||||
|
int xml = 1; /* default Issue 64 */
|
||||||
|
|
||||||
|
if (ctxt == NULL)
|
||||||
|
return(-1);
|
||||||
|
if ((nr < 0) || (nr >= ctxt->incNr))
|
||||||
|
return(-1);
|
||||||
|
cur = ctxt->incTab[nr];
|
||||||
|
if (cur == NULL)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
#ifdef DEBUG_XINCLUDE
|
||||||
|
xmlDebugDumpNode(stdout, cur, 0);
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* read the attributes
|
||||||
|
*/
|
||||||
|
href = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_HREF);
|
||||||
|
if (href == NULL) {
|
||||||
|
href = xmlGetProp(cur, XINCLUDE_HREF);
|
||||||
|
if (href == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext, "XInclude: no href\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parse = xmlGetNsProp(cur, XINCLUDE_NS, XINCLUDE_PARSE);
|
||||||
|
if (parse == NULL) {
|
||||||
|
parse = xmlGetProp(cur, XINCLUDE_PARSE);
|
||||||
|
}
|
||||||
|
if (parse != NULL) {
|
||||||
|
if (xmlStrEqual(parse, XINCLUDE_PARSE_XML))
|
||||||
|
xml = 1;
|
||||||
|
else if (xmlStrEqual(parse, XINCLUDE_PARSE_TEXT))
|
||||||
|
xml = 0;
|
||||||
|
else {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"XInclude: invalid value %s for %s\n",
|
||||||
|
parse, XINCLUDE_PARSE);
|
||||||
|
if (href != NULL)
|
||||||
|
xmlFree(href);
|
||||||
|
if (parse != NULL)
|
||||||
|
xmlFree(parse);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* compute the URI
|
||||||
|
*/
|
||||||
|
base = xmlNodeGetBase(ctxt->doc, cur);
|
||||||
|
URI = xmlBuildURI(href, base);
|
||||||
|
if (URI == NULL) {
|
||||||
|
xmlChar *escbase;
|
||||||
|
xmlChar *eschref;
|
||||||
|
/*
|
||||||
|
* Some escapeing may be needed
|
||||||
|
*/
|
||||||
|
escbase = xmlURIEscape(base);
|
||||||
|
eschref = xmlURIEscape(href);
|
||||||
|
URI = xmlBuildURI(eschref, escbase);
|
||||||
|
if (escbase != NULL)
|
||||||
|
xmlFree(escbase);
|
||||||
|
if (eschref != NULL)
|
||||||
|
xmlFree(eschref);
|
||||||
|
}
|
||||||
|
if (URI == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext, "XInclude: failed build URL\n");
|
||||||
|
if (parse != NULL)
|
||||||
|
xmlFree(parse);
|
||||||
|
if (href != NULL)
|
||||||
|
xmlFree(href);
|
||||||
|
if (base != NULL)
|
||||||
|
xmlFree(base);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_XINCLUDE
|
||||||
|
xmlGenericError(xmlGenericErrorContext, "parse: %s\n",
|
||||||
|
xml ? "xml": "text");
|
||||||
|
xmlGenericError(xmlGenericErrorContext, "URI: %s\n", URI);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cleanup
|
||||||
|
*/
|
||||||
|
if (xml) {
|
||||||
|
xmlXIncludeLoadDoc(ctxt, URI, nr);
|
||||||
|
/* xmlXIncludeGetFragment(ctxt, cur, URI); */
|
||||||
|
} else {
|
||||||
|
xmlXIncludeLoadTxt(ctxt, URI, nr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cleanup
|
||||||
|
*/
|
||||||
|
if (URI != NULL)
|
||||||
|
xmlFree(URI);
|
||||||
|
if (parse != NULL)
|
||||||
|
xmlFree(parse);
|
||||||
|
if (href != NULL)
|
||||||
|
xmlFree(href);
|
||||||
|
if (base != NULL)
|
||||||
|
xmlFree(base);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeIncludeNode:
|
||||||
|
* @ctxt: an XInclude context
|
||||||
|
* @nr: the node number
|
||||||
|
*
|
||||||
|
* Inplement the infoset replacement for the given node
|
||||||
|
*
|
||||||
|
* Returns 0 if substition succeeded, -1 if some processing failed
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlXIncludeIncludeNode(xmlXIncludeCtxtPtr ctxt, int nr) {
|
||||||
|
xmlNodePtr cur, end, list;
|
||||||
|
|
||||||
|
if (ctxt == NULL)
|
||||||
|
return(-1);
|
||||||
|
if ((nr < 0) || (nr >= ctxt->incNr))
|
||||||
|
return(-1);
|
||||||
|
cur = ctxt->incTab[nr];
|
||||||
|
if (cur == NULL)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change the current node as an XInclude start one, and add an
|
||||||
|
* entity end one
|
||||||
|
*/
|
||||||
|
cur->type = XML_XINCLUDE_START;
|
||||||
|
end = xmlNewNode(cur->ns, cur->name);
|
||||||
|
if (end == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"XInclude: failed to build node\n");
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
end->type = XML_XINCLUDE_END;
|
||||||
|
xmlAddNextSibling(cur, end);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add the list of nodes
|
||||||
|
*/
|
||||||
|
list = ctxt->repTab[nr];
|
||||||
|
ctxt->repTab[nr] = NULL;
|
||||||
|
while (list != NULL) {
|
||||||
|
cur = list;
|
||||||
|
list = list->next;
|
||||||
|
|
||||||
|
xmlAddPrevSibling(end, cur);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeTestNode:
|
||||||
|
* @doc: an XML document
|
||||||
|
* @node: an XInclude node
|
||||||
|
*
|
||||||
|
* test if the node is an XInclude node
|
||||||
|
*
|
||||||
|
* Returns 1 true, 0 otherwise
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlXIncludeTestNode(xmlDocPtr doc, xmlNodePtr node) {
|
||||||
|
if (node == NULL)
|
||||||
|
return(0);
|
||||||
|
if (node->ns == NULL)
|
||||||
|
return(0);
|
||||||
|
if ((xmlStrEqual(node->name, XINCLUDE_NODE)) &&
|
||||||
|
(xmlStrEqual(node->ns->href, XINCLUDE_NS))) return(1);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xmlXIncludeProcess:
|
||||||
|
* @doc: an XML document
|
||||||
|
*
|
||||||
|
* Implement the XInclude substitution on the XML document @doc
|
||||||
|
*
|
||||||
|
* Returns 0 if no substition were done, -1 if some processing failed
|
||||||
|
* or the number of substitutions done.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
xmlXIncludeProcess(xmlDocPtr doc) {
|
||||||
|
xmlXIncludeCtxtPtr ctxt;
|
||||||
|
xmlNodePtr cur;
|
||||||
|
int ret = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (doc == NULL)
|
||||||
|
return(-1);
|
||||||
|
ctxt = xmlXIncludeNewContext(doc);
|
||||||
|
if (ctxt == NULL)
|
||||||
|
return(-1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* First phase: lookup the elements in the document
|
||||||
|
*/
|
||||||
|
cur = xmlDocGetRootElement(doc);
|
||||||
|
if (xmlXIncludeTestNode(doc, cur))
|
||||||
|
xmlXIncludePreProcessNode(ctxt, cur);
|
||||||
|
while (cur != NULL) {
|
||||||
|
/* TODO: need to work on entities -> stack */
|
||||||
|
if ((cur->children != NULL) &&
|
||||||
|
(cur->children->type != XML_ENTITY_DECL)) {
|
||||||
|
cur = cur->children;
|
||||||
|
if (xmlXIncludeTestNode(doc, cur))
|
||||||
|
xmlXIncludePreProcessNode(ctxt, cur);
|
||||||
|
} else if (cur->next != NULL) {
|
||||||
|
cur = cur->next;
|
||||||
|
if (xmlXIncludeTestNode(doc, cur))
|
||||||
|
xmlXIncludePreProcessNode(ctxt, cur);
|
||||||
|
} else {
|
||||||
|
do {
|
||||||
|
cur = cur->parent;
|
||||||
|
if (cur == NULL) break; /* do */
|
||||||
|
if (cur->next != NULL) {
|
||||||
|
cur = cur->next;
|
||||||
|
if (xmlXIncludeTestNode(doc, cur))
|
||||||
|
xmlXIncludePreProcessNode(ctxt, cur);
|
||||||
|
break; /* do */
|
||||||
|
}
|
||||||
|
} while (cur != NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Second Phase : collect the infosets fragments
|
||||||
|
*/
|
||||||
|
for (i = 0;i < ctxt->incNr; i++) {
|
||||||
|
xmlXIncludeLoadNode(ctxt, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Third phase: extend the original document infoset.
|
||||||
|
*/
|
||||||
|
for (i = 0;i < ctxt->incNr; i++) {
|
||||||
|
xmlXIncludeIncludeNode(ctxt, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cleanup
|
||||||
|
*/
|
||||||
|
xmlXIncludeFreeContext(ctxt);
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* !LIBXML_XINCLUDE_ENABLED */
|
||||||
|
#endif
|
26
xinclude.h
Normal file
26
xinclude.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* xinclude.c : API to handle XInclude processing
|
||||||
|
*
|
||||||
|
* World Wide Web Consortium Working Draft 26 October 2000
|
||||||
|
* http://www.w3.org/TR/2000/WD-xinclude-20001026
|
||||||
|
*
|
||||||
|
* See Copyright for the status of this software.
|
||||||
|
*
|
||||||
|
* Daniel.Veillard@w3.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XML_XINCLUDE_H__
|
||||||
|
#define __XML_XINCLUDE_H__
|
||||||
|
|
||||||
|
#include <libxml/tree.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int xmlXIncludeProcess (xmlDocPtr doc);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* __XML_XINCLUDE_H__ */
|
24
xmllint.c
24
xmllint.c
@ -55,6 +55,9 @@
|
|||||||
#include <libxml/xpath.h>
|
#include <libxml/xpath.h>
|
||||||
#include <libxml/debugXML.h>
|
#include <libxml/debugXML.h>
|
||||||
#include <libxml/xmlerror.h>
|
#include <libxml/xmlerror.h>
|
||||||
|
#ifdef LIBXML_XINCLUDE_ENABLED
|
||||||
|
#include <libxml/xinclude.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LIBXML_DEBUG_ENABLED
|
#ifdef LIBXML_DEBUG_ENABLED
|
||||||
static int debug = 0;
|
static int debug = 0;
|
||||||
@ -81,6 +84,9 @@ static int memory = 0;
|
|||||||
static int noblanks = 0;
|
static int noblanks = 0;
|
||||||
static int testIO = 0;
|
static int testIO = 0;
|
||||||
static char *encoding = NULL;
|
static char *encoding = NULL;
|
||||||
|
#ifdef LIBXML_XINCLUDE_ENABLED
|
||||||
|
static int xinclude = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern int xmlDoValidityCheckingDefaultValue;
|
extern int xmlDoValidityCheckingDefaultValue;
|
||||||
extern int xmlGetWarningsDefaultValue;
|
extern int xmlGetWarningsDefaultValue;
|
||||||
@ -497,10 +503,14 @@ void parseAndPrintFile(char *filename) {
|
|||||||
/*
|
/*
|
||||||
* If we don't have a document we might as well give up. Do we
|
* If we don't have a document we might as well give up. Do we
|
||||||
* want an error message here? <sven@zen.org> */
|
* want an error message here? <sven@zen.org> */
|
||||||
if (doc == NULL)
|
if (doc == NULL) {
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LIBXML_XINCLUDE_ENABLED
|
||||||
|
if (xinclude)
|
||||||
|
xmlXIncludeProcess(doc);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LIBXML_DEBUG_ENABLED
|
#ifdef LIBXML_DEBUG_ENABLED
|
||||||
/*
|
/*
|
||||||
@ -667,6 +677,11 @@ int main(int argc, char **argv) {
|
|||||||
else if ((!strcmp(argv[i], "-testIO")) ||
|
else if ((!strcmp(argv[i], "-testIO")) ||
|
||||||
(!strcmp(argv[i], "--testIO")))
|
(!strcmp(argv[i], "--testIO")))
|
||||||
testIO++;
|
testIO++;
|
||||||
|
#ifdef LIBXML_XINCLUDE_ENABLED
|
||||||
|
else if ((!strcmp(argv[i], "-xinclude")) ||
|
||||||
|
(!strcmp(argv[i], "--xinclude")))
|
||||||
|
xinclude++;
|
||||||
|
#endif
|
||||||
else if ((!strcmp(argv[i], "-compress")) ||
|
else if ((!strcmp(argv[i], "-compress")) ||
|
||||||
(!strcmp(argv[i], "--compress"))) {
|
(!strcmp(argv[i], "--compress"))) {
|
||||||
compress++;
|
compress++;
|
||||||
@ -773,6 +788,9 @@ int main(int argc, char **argv) {
|
|||||||
printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
|
printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
|
||||||
printf("\t--testIO : test user I/O support\n");
|
printf("\t--testIO : test user I/O support\n");
|
||||||
printf("\t--encode encoding : output in the given encoding\n");
|
printf("\t--encode encoding : output in the given encoding\n");
|
||||||
|
#ifdef LIBXML_XINCLUDE_ENABLED
|
||||||
|
printf("\t--xinclude : do XInclude processing\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
xmlCleanupParser();
|
xmlCleanupParser();
|
||||||
xmlMemoryDump();
|
xmlMemoryDump();
|
||||||
|
@ -77,6 +77,15 @@ extern void xmlCheckVersion(int version);
|
|||||||
#define LIBXML_XPTR_DISABLED
|
#define LIBXML_XPTR_DISABLED
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Whether XInclude is configured in
|
||||||
|
*/
|
||||||
|
#if @WITH_XINCLUDE@
|
||||||
|
#define LIBXML_XINCLUDE_ENABLED
|
||||||
|
#else
|
||||||
|
#define LIBXML_XINCLUDE_DISABLED
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Whether iconv support is available
|
* Whether iconv support is available
|
||||||
*/
|
*/
|
||||||
|
150
xpath.c
150
xpath.c
@ -597,20 +597,51 @@ xmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
|
|||||||
*/
|
*/
|
||||||
xmlNodeSetPtr
|
xmlNodeSetPtr
|
||||||
xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
|
xmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
|
||||||
int i;
|
int i, j, initNr;
|
||||||
|
|
||||||
if (val2 == NULL) return(val1);
|
if (val2 == NULL) return(val1);
|
||||||
if (val1 == NULL) {
|
if (val1 == NULL) {
|
||||||
val1 = xmlXPathNodeSetCreate(NULL);
|
val1 = xmlXPathNodeSetCreate(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
initNr = val1->nodeNr;
|
||||||
* !!!!! this can be optimized a lot, knowing that both
|
|
||||||
* val1 and val2 already have unicity of their values.
|
|
||||||
*/
|
|
||||||
|
|
||||||
for (i = 0;i < val2->nodeNr;i++)
|
for (i = 0;i < val2->nodeNr;i++) {
|
||||||
xmlXPathNodeSetAdd(val1, val2->nodeTab[i]);
|
/*
|
||||||
|
* check against doublons
|
||||||
|
*/
|
||||||
|
for (j = 0; j < initNr; j++)
|
||||||
|
if (val1->nodeTab[j] == val2->nodeTab[i]) continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* grow the nodeTab if needed
|
||||||
|
*/
|
||||||
|
if (val1->nodeMax == 0) {
|
||||||
|
val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
|
||||||
|
sizeof(xmlNodePtr));
|
||||||
|
if (val1->nodeTab == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"xmlXPathNodeSetMerge: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
memset(val1->nodeTab, 0 ,
|
||||||
|
XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
|
||||||
|
val1->nodeMax = XML_NODESET_DEFAULT;
|
||||||
|
} else if (val1->nodeNr == val1->nodeMax) {
|
||||||
|
xmlNodePtr *temp;
|
||||||
|
|
||||||
|
val1->nodeMax *= 2;
|
||||||
|
temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
|
||||||
|
sizeof(xmlNodePtr));
|
||||||
|
if (temp == NULL) {
|
||||||
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
|
"xmlXPathNodeSetMerge: out of memory\n");
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
val1->nodeTab = temp;
|
||||||
|
}
|
||||||
|
val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i];
|
||||||
|
}
|
||||||
|
|
||||||
return(val1);
|
return(val1);
|
||||||
}
|
}
|
||||||
@ -1922,12 +1953,12 @@ typedef xmlNodePtr (*xmlXPathTraversalFunction)
|
|||||||
(xmlXPathParserContextPtr ctxt, xmlNodePtr cur);
|
(xmlXPathParserContextPtr ctxt, xmlNodePtr cur);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mlXPathNextSelf:
|
* xmlXPathNextSelf:
|
||||||
* @ctxt: the XPath Parser context
|
* @ctxt: the XPath Parser context
|
||||||
* @cur: the current node in the traversal
|
* @cur: the current node in the traversal
|
||||||
*
|
*
|
||||||
* Traversal function for the "self" direction
|
* Traversal function for the "self" direction
|
||||||
* he self axis contains just the context node itself
|
* The self axis contains just the context node itself
|
||||||
*
|
*
|
||||||
* Returns the next element following that axis
|
* Returns the next element following that axis
|
||||||
*/
|
*/
|
||||||
@ -1939,7 +1970,7 @@ xmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mlXPathNextChild:
|
* xmlXPathNextChild:
|
||||||
* @ctxt: the XPath Parser context
|
* @ctxt: the XPath Parser context
|
||||||
* @cur: the current node in the traversal
|
* @cur: the current node in the traversal
|
||||||
*
|
*
|
||||||
@ -1976,6 +2007,8 @@ xmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
case XML_ENTITY_DECL:
|
case XML_ENTITY_DECL:
|
||||||
case XML_ATTRIBUTE_NODE:
|
case XML_ATTRIBUTE_NODE:
|
||||||
case XML_NAMESPACE_DECL:
|
case XML_NAMESPACE_DECL:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
return(NULL);
|
return(NULL);
|
||||||
}
|
}
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@ -1987,7 +2020,7 @@ xmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mlXPathNextDescendant:
|
* xmlXPathNextDescendant:
|
||||||
* @ctxt: the XPath Parser context
|
* @ctxt: the XPath Parser context
|
||||||
* @cur: the current node in the traversal
|
* @cur: the current node in the traversal
|
||||||
*
|
*
|
||||||
@ -2002,7 +2035,8 @@ xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
if (ctxt->context->node == NULL)
|
if (ctxt->context->node == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
if (ctxt->context->node->type == XML_ATTRIBUTE_NODE)
|
if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
|
||||||
|
(ctxt->context->node->type == XML_NAMESPACE_DECL))
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
|
if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
|
||||||
@ -2030,7 +2064,7 @@ xmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mlXPathNextDescendantOrSelf:
|
* xmlXPathNextDescendantOrSelf:
|
||||||
* @ctxt: the XPath Parser context
|
* @ctxt: the XPath Parser context
|
||||||
* @cur: the current node in the traversal
|
* @cur: the current node in the traversal
|
||||||
*
|
*
|
||||||
@ -2047,7 +2081,8 @@ xmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
if (ctxt->context->node == NULL)
|
if (ctxt->context->node == NULL)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
if (ctxt->context->node->type == XML_ATTRIBUTE_NODE)
|
if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
|
||||||
|
(ctxt->context->node->type == XML_NAMESPACE_DECL))
|
||||||
return(NULL);
|
return(NULL);
|
||||||
return(ctxt->context->node);
|
return(ctxt->context->node);
|
||||||
}
|
}
|
||||||
@ -2086,6 +2121,8 @@ xmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
case XML_DTD_NODE:
|
case XML_DTD_NODE:
|
||||||
case XML_ELEMENT_DECL:
|
case XML_ELEMENT_DECL:
|
||||||
case XML_ATTRIBUTE_DECL:
|
case XML_ATTRIBUTE_DECL:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
case XML_ENTITY_DECL:
|
case XML_ENTITY_DECL:
|
||||||
if (ctxt->context->node->parent == NULL)
|
if (ctxt->context->node->parent == NULL)
|
||||||
return((xmlNodePtr) ctxt->context->doc);
|
return((xmlNodePtr) ctxt->context->doc);
|
||||||
@ -2151,6 +2188,8 @@ xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
case XML_ATTRIBUTE_DECL:
|
case XML_ATTRIBUTE_DECL:
|
||||||
case XML_ENTITY_DECL:
|
case XML_ENTITY_DECL:
|
||||||
case XML_NOTATION_NODE:
|
case XML_NOTATION_NODE:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
if (ctxt->context->node->parent == NULL)
|
if (ctxt->context->node->parent == NULL)
|
||||||
return((xmlNodePtr) ctxt->context->doc);
|
return((xmlNodePtr) ctxt->context->doc);
|
||||||
return(ctxt->context->node->parent);
|
return(ctxt->context->node->parent);
|
||||||
@ -2194,6 +2233,8 @@ xmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
case XML_ELEMENT_DECL:
|
case XML_ELEMENT_DECL:
|
||||||
case XML_ATTRIBUTE_DECL:
|
case XML_ATTRIBUTE_DECL:
|
||||||
case XML_ENTITY_DECL:
|
case XML_ENTITY_DECL:
|
||||||
|
case XML_XINCLUDE_START:
|
||||||
|
case XML_XINCLUDE_END:
|
||||||
return(cur->parent);
|
return(cur->parent);
|
||||||
case XML_ATTRIBUTE_NODE: {
|
case XML_ATTRIBUTE_NODE: {
|
||||||
xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
|
xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
|
||||||
@ -2252,6 +2293,9 @@ xmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
*/
|
*/
|
||||||
xmlNodePtr
|
xmlNodePtr
|
||||||
xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
||||||
|
if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
|
||||||
|
(ctxt->context->node->type == XML_NAMESPACE_DECL))
|
||||||
|
return(NULL);
|
||||||
if (cur == (xmlNodePtr) ctxt->context->doc)
|
if (cur == (xmlNodePtr) ctxt->context->doc)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
if (cur == NULL)
|
if (cur == NULL)
|
||||||
@ -2273,6 +2317,9 @@ xmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
*/
|
*/
|
||||||
xmlNodePtr
|
xmlNodePtr
|
||||||
xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
xmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
||||||
|
if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
|
||||||
|
(ctxt->context->node->type == XML_NAMESPACE_DECL))
|
||||||
|
return(NULL);
|
||||||
if (cur == (xmlNodePtr) ctxt->context->doc)
|
if (cur == (xmlNodePtr) ctxt->context->doc)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
if (cur == NULL)
|
if (cur == NULL)
|
||||||
@ -2303,7 +2350,7 @@ xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
do {
|
do {
|
||||||
cur = cur->parent;
|
cur = cur->parent;
|
||||||
if (cur == NULL) return(NULL);
|
if (cur == NULL) return(NULL);
|
||||||
if (cur == ctxt->context->doc->children) return(NULL); /* !!!!!?!? */
|
if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL);
|
||||||
if (cur->next != NULL) return(cur->next);
|
if (cur->next != NULL) return(cur->next);
|
||||||
} while (cur != NULL);
|
} while (cur != NULL);
|
||||||
return(cur);
|
return(cur);
|
||||||
@ -2320,13 +2367,18 @@ xmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
xmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
|
xmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
|
||||||
xmlNodePtr tmp ;
|
if ((ancestor == NULL) || (node == NULL)) return(0);
|
||||||
if (ancestor == NULL || node == NULL) return 0 ;
|
/* nodes need to be in the same document */
|
||||||
for (tmp = node ; tmp->parent != NULL ; tmp = tmp->parent) {
|
if (ancestor->doc != node->doc) return(0);
|
||||||
if (tmp->parent == ancestor)
|
/* avoid searching if ancestor or node is the root node */
|
||||||
return 1 ;
|
if (ancestor == (xmlNodePtr) node->doc) return(1);
|
||||||
|
if (node == (xmlNodePtr) ancestor->doc) return(0);
|
||||||
|
while (node->parent != NULL) {
|
||||||
|
if (node->parent == ancestor)
|
||||||
|
return(1);
|
||||||
|
node = node->parent;
|
||||||
}
|
}
|
||||||
return 0 ;
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2372,8 +2424,9 @@ xmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
|||||||
*
|
*
|
||||||
* Returns the next element following that axis
|
* Returns the next element following that axis
|
||||||
*/
|
*/
|
||||||
xmlNsPtr
|
xmlNodePtr
|
||||||
xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlAttrPtr cur) {
|
xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
||||||
|
if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
|
||||||
if ((cur == NULL) || (ctxt->context->namespaces == NULL)) {
|
if ((cur == NULL) || (ctxt->context->namespaces == NULL)) {
|
||||||
if (ctxt->context->namespaces != NULL)
|
if (ctxt->context->namespaces != NULL)
|
||||||
xmlFree(ctxt->context->namespaces);
|
xmlFree(ctxt->context->namespaces);
|
||||||
@ -2382,7 +2435,7 @@ xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlAttrPtr cur) {
|
|||||||
if (ctxt->context->namespaces == NULL) return(NULL);
|
if (ctxt->context->namespaces == NULL) return(NULL);
|
||||||
ctxt->context->nsNr = 0;
|
ctxt->context->nsNr = 0;
|
||||||
}
|
}
|
||||||
return(ctxt->context->namespaces[ctxt->context->nsNr++]);
|
return((xmlNodePtr)ctxt->context->namespaces[ctxt->context->nsNr++]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2395,14 +2448,15 @@ xmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlAttrPtr cur) {
|
|||||||
*
|
*
|
||||||
* Returns the next element following that axis
|
* Returns the next element following that axis
|
||||||
*/
|
*/
|
||||||
xmlAttrPtr
|
xmlNodePtr
|
||||||
xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlAttrPtr cur) {
|
xmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
|
||||||
|
if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
|
||||||
if (cur == NULL) {
|
if (cur == NULL) {
|
||||||
if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
|
if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
|
||||||
return(NULL);
|
return(NULL);
|
||||||
return(ctxt->context->node->properties);
|
return((xmlNodePtr)ctxt->context->node->properties);
|
||||||
}
|
}
|
||||||
return(cur->next);
|
return((xmlNodePtr)cur->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -2483,7 +2537,7 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|||||||
xmlGenericError(xmlGenericErrorContext,
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
"axis 'attributes' ");
|
"axis 'attributes' ");
|
||||||
#endif
|
#endif
|
||||||
next = (xmlXPathTraversalFunction) xmlXPathNextAttribute; break;
|
next = xmlXPathNextAttribute; break;
|
||||||
break;
|
break;
|
||||||
case AXIS_CHILD:
|
case AXIS_CHILD:
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
@ -2637,17 +2691,33 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NODE_TEST_ALL:
|
case NODE_TEST_ALL:
|
||||||
if ((cur->type == XML_ELEMENT_NODE) ||
|
if (axis == AXIS_ATTRIBUTE) {
|
||||||
(cur->type == XML_DOCUMENT_NODE) ||
|
if (cur->type == XML_ATTRIBUTE_NODE) {
|
||||||
(cur->type == XML_HTML_DOCUMENT_NODE)) {
|
|
||||||
#ifdef DEBUG_STEP
|
#ifdef DEBUG_STEP
|
||||||
n++;
|
n++;
|
||||||
#endif
|
#endif
|
||||||
xmlXPathNodeSetAdd(ret, cur);
|
xmlXPathNodeSetAdd(ret, cur);
|
||||||
|
}
|
||||||
|
} else if (axis == AXIS_NAMESPACE) {
|
||||||
|
if (cur->type == XML_NAMESPACE_DECL) {
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
n++;
|
||||||
|
#endif
|
||||||
|
xmlXPathNodeSetAdd(ret, cur);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((cur->type == XML_ELEMENT_NODE) ||
|
||||||
|
(cur->type == XML_DOCUMENT_NODE) ||
|
||||||
|
(cur->type == XML_HTML_DOCUMENT_NODE)) {
|
||||||
|
#ifdef DEBUG_STEP
|
||||||
|
n++;
|
||||||
|
#endif
|
||||||
|
xmlXPathNodeSetAdd(ret, cur);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NODE_TEST_NS: {
|
case NODE_TEST_NS: {
|
||||||
TODO /* namespace search */
|
TODO;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NODE_TEST_NAME:
|
case NODE_TEST_NAME:
|
||||||
@ -2673,6 +2743,10 @@ xmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt, xmlXPathAxisVal axis,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case XML_NAMESPACE_DECL: {
|
||||||
|
TODO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2720,6 +2794,7 @@ xmlXPathRoot(xmlXPathParserContextPtr ctxt) {
|
|||||||
* @ctxt: the XPath Parser context
|
* @ctxt: the XPath Parser context
|
||||||
*
|
*
|
||||||
* Implement the last() XPath function
|
* Implement the last() XPath function
|
||||||
|
* number last()
|
||||||
* The last function returns the number of nodes in the context node list.
|
* The last function returns the number of nodes in the context node list.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -2913,6 +2988,10 @@ xmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
valuePush(ctxt,
|
valuePush(ctxt,
|
||||||
xmlXPathNewString(cur->nodesetval->nodeTab[i]->name));
|
xmlXPathNewString(cur->nodesetval->nodeTab[i]->name));
|
||||||
break;
|
break;
|
||||||
|
case XML_NAMESPACE_DECL:
|
||||||
|
valuePush(ctxt, xmlXPathNewString(
|
||||||
|
((xmlNsPtr)cur->nodesetval->nodeTab[i])->prefix));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
valuePush(ctxt, xmlXPathNewCString(""));
|
valuePush(ctxt, xmlXPathNewCString(""));
|
||||||
}
|
}
|
||||||
@ -4572,6 +4651,7 @@ xmlXPathEvalUnionExpr(xmlXPathParserContextPtr ctxt) {
|
|||||||
obj2 = valuePop(ctxt);
|
obj2 = valuePop(ctxt);
|
||||||
obj1->nodesetval = xmlXPathNodeSetMerge(obj1->nodesetval,
|
obj1->nodesetval = xmlXPathNodeSetMerge(obj1->nodesetval,
|
||||||
obj2->nodesetval);
|
obj2->nodesetval);
|
||||||
|
valuePush(ctxt, obj1);
|
||||||
xmlXPathFreeObject(obj2);
|
xmlXPathFreeObject(obj2);
|
||||||
SKIP_BLANKS;
|
SKIP_BLANKS;
|
||||||
}
|
}
|
||||||
|
46
xpointer.c
46
xpointer.c
@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <libxml/xpointer.h>
|
#include <libxml/xpointer.h>
|
||||||
#include <libxml/xmlmemory.h>
|
#include <libxml/xmlmemory.h>
|
||||||
#include <libxml/parserInternals.h>
|
#include <libxml/parserInternals.h>
|
||||||
@ -1711,8 +1712,13 @@ xmlXPtrInsideRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
|
|||||||
if (node->content == NULL) {
|
if (node->content == NULL) {
|
||||||
return(xmlXPtrNewRange(node, 0, node, 0));
|
return(xmlXPtrNewRange(node, 0, node, 0));
|
||||||
} else {
|
} else {
|
||||||
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
return(xmlXPtrNewRange(node, 0, node,
|
return(xmlXPtrNewRange(node, 0, node,
|
||||||
xmlStrlen(node->content)));
|
xmlStrlen(node->content)));
|
||||||
|
#else
|
||||||
|
return(xmlXPtrNewRange(node, 0, node,
|
||||||
|
xmlBufferLength(node->content)));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case XML_ATTRIBUTE_NODE:
|
case XML_ATTRIBUTE_NODE:
|
||||||
@ -1743,8 +1749,13 @@ xmlXPtrInsideRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
|
|||||||
if (node->content == NULL) {
|
if (node->content == NULL) {
|
||||||
return(xmlXPtrNewRange(node, 0, node, 0));
|
return(xmlXPtrNewRange(node, 0, node, 0));
|
||||||
} else {
|
} else {
|
||||||
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
return(xmlXPtrNewRange(node, 0, node,
|
return(xmlXPtrNewRange(node, 0, node,
|
||||||
xmlStrlen(node->content)));
|
xmlStrlen(node->content)));
|
||||||
|
#else
|
||||||
|
return(xmlXPtrNewRange(node, 0, node,
|
||||||
|
xmlBufferLength(node->content)));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case XML_ATTRIBUTE_NODE:
|
case XML_ATTRIBUTE_NODE:
|
||||||
@ -2010,7 +2021,11 @@ xmlXPtrAdvanceChar(xmlNodePtr *node, int *index, int bytes) {
|
|||||||
*/
|
*/
|
||||||
len = 0;
|
len = 0;
|
||||||
if (cur->content != NULL) {
|
if (cur->content != NULL) {
|
||||||
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
len = xmlStrlen(cur->content);
|
len = xmlStrlen(cur->content);
|
||||||
|
#else
|
||||||
|
len = xmlBufferLength(cur->content);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
if (pos > len) {
|
if (pos > len) {
|
||||||
/* Strange, the index in the text node is greater than it's len */
|
/* Strange, the index in the text node is greater than it's len */
|
||||||
@ -2072,9 +2087,18 @@ xmlXPtrMatchString(const xmlChar *string, xmlNodePtr start, int startindex,
|
|||||||
if ((cur == *end) && (pos + stringlen > *endindex))
|
if ((cur == *end) && (pos + stringlen > *endindex))
|
||||||
return(0);
|
return(0);
|
||||||
if (cur->content != NULL) {
|
if (cur->content != NULL) {
|
||||||
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
len = xmlStrlen(cur->content);
|
len = xmlStrlen(cur->content);
|
||||||
|
#else
|
||||||
|
len = xmlBufferLength(cur->content);
|
||||||
|
#endif
|
||||||
if (len >= pos + stringlen) {
|
if (len >= pos + stringlen) {
|
||||||
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
match = (!xmlStrncmp(&cur->content[pos], string, stringlen));
|
match = (!xmlStrncmp(&cur->content[pos], string, stringlen));
|
||||||
|
#else
|
||||||
|
len = (!xmlStrncmp(&xmlBufferContent(cur->content)[pos],
|
||||||
|
string, stringlen));
|
||||||
|
#endif
|
||||||
if (match) {
|
if (match) {
|
||||||
#ifdef DEBUG_RANGES
|
#ifdef DEBUG_RANGES
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
@ -2091,7 +2115,12 @@ xmlXPtrMatchString(const xmlChar *string, xmlNodePtr start, int startindex,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int sub = len - pos;
|
int sub = len - pos;
|
||||||
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
match = (!xmlStrncmp(&cur->content[pos], string, sub));
|
match = (!xmlStrncmp(&cur->content[pos], string, sub));
|
||||||
|
#else
|
||||||
|
len = (!xmlStrncmp(&xmlBufferContent(cur->content)[pos],
|
||||||
|
string, sub));
|
||||||
|
#endif
|
||||||
if (match) {
|
if (match) {
|
||||||
#ifdef DEBUG_RANGES
|
#ifdef DEBUG_RANGES
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
@ -2156,12 +2185,21 @@ xmlXPtrSearchString(const xmlChar *string, xmlNodePtr *start, int *startindex,
|
|||||||
|
|
||||||
while (cur != NULL) {
|
while (cur != NULL) {
|
||||||
if (cur->content != NULL) {
|
if (cur->content != NULL) {
|
||||||
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
len = xmlStrlen(cur->content);
|
len = xmlStrlen(cur->content);
|
||||||
|
#else
|
||||||
|
len = xmlBufferLength(cur->content);
|
||||||
|
#endif
|
||||||
while (pos <= len) {
|
while (pos <= len) {
|
||||||
if (first != 0) {
|
if (first != 0) {
|
||||||
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
str = xmlStrchr(&cur->content[pos], first);
|
str = xmlStrchr(&cur->content[pos], first);
|
||||||
|
#else
|
||||||
|
str = xmlStrchr(&xmlBufferContent(cur->content)[pos],
|
||||||
|
first);
|
||||||
|
#endif
|
||||||
if (str != NULL) {
|
if (str != NULL) {
|
||||||
pos = (str - cur->content);
|
pos = (str - (xmlChar *)(cur->content));
|
||||||
#ifdef DEBUG_RANGES
|
#ifdef DEBUG_RANGES
|
||||||
xmlGenericError(xmlGenericErrorContext,
|
xmlGenericError(xmlGenericErrorContext,
|
||||||
"found '%c' at index %d of ->",
|
"found '%c' at index %d of ->",
|
||||||
@ -2244,7 +2282,11 @@ xmlXPtrGetLastChar(xmlNodePtr *node, int *index) {
|
|||||||
if (cur->last != NULL)
|
if (cur->last != NULL)
|
||||||
cur = cur->last;
|
cur = cur->last;
|
||||||
else if (cur->content != NULL) {
|
else if (cur->content != NULL) {
|
||||||
|
#ifndef XML_USE_BUFFER_CONTENT
|
||||||
len = xmlStrlen(cur->content);
|
len = xmlStrlen(cur->content);
|
||||||
|
#else
|
||||||
|
len = xmlBufferLength(cur->content);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2459,7 +2501,7 @@ xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
|
|||||||
xmlXPtrNewRange(start, startindex,
|
xmlXPtrNewRange(start, startindex,
|
||||||
rend, rindex));
|
rend, rindex));
|
||||||
}
|
}
|
||||||
} else if (num <= 0) {
|
} else if ((number != NULL) && (num <= 0)) {
|
||||||
xmlXPtrLocationSetAdd(newset,
|
xmlXPtrLocationSetAdd(newset,
|
||||||
xmlXPtrNewRange(start, startindex,
|
xmlXPtrNewRange(start, startindex,
|
||||||
start, startindex));
|
start, startindex));
|
||||||
|
Reference in New Issue
Block a user