tree.c revision 750a460541832b63ec5de36374a749782ea2c9bc
/*
* tree.c : implementation of access function for an XML tree.
*
* References:
* XHTML 1.0 W3C REC: http://www.w3.org/TR/2002/REC-xhtml1-20020801/
*
* See Copyright for the status of this software.
*
* daniel@veillard.com
*
*/
#define IN_LIBXML
#include "libxml.h"
#include <string.h> /* for memset() only ! */
#include <limits.h>
#ifdef HAVE_CTYPE_H
#include <ctype.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_ZLIB_H
#include <zlib.h>
#endif
#include <libxml/xmlmemory.h>
#include <libxml/entities.h>
#include <libxml/xmlerror.h>
#include <libxml/parserInternals.h>
#ifdef LIBXML_HTML_ENABLED
#include <libxml/HTMLtree.h>
#endif
#ifdef LIBXML_DEBUG_ENABLED
#include <libxml/debugXML.h>
#endif
int __xmlRegisterCallbacks = 0;
/************************************************************************
* *
* Forward declarations *
* *
************************************************************************/
/************************************************************************
* *
* Tree memory error handler *
* *
************************************************************************/
/**
* xmlTreeErrMemory:
* @extra: extra informations
*
* Handle an out of memory condition
*/
static void
xmlTreeErrMemory(const char *extra)
{
}
/**
* xmlTreeErr:
* @code: the error number
* @extra: extra informations
*
* Handle an out of memory condition
*/
static void
{
switch(code) {
case XML_TREE_INVALID_HEX:
msg = "invalid hexadecimal character value\n";
break;
case XML_TREE_INVALID_DEC:
msg = "invalid decimal character value\n";
break;
msg = "unterminated entity reference %15s\n";
break;
default:
msg = "unexpected error number\n";
}
}
/************************************************************************
* *
* A few static variables and macros *
* *
************************************************************************/
/* #undef xmlStringText */
/* #undef xmlStringTextNoenc */
const xmlChar xmlStringTextNoenc[] =
{ 't', 'e', 'x', 't', 'n', 'o', 'e', 'n', 'c', 0 };
/* #undef xmlStringComment */
static int xmlCompressMode = 0;
static int xmlCheckDTD = 1;
#define UPDATE_LAST_CHILD_AND_PARENT(n) if ((n) != NULL) { \
} else { \
} \
}}
/* #define DEBUG_BUFFER */
/* #define DEBUG_TREE */
/************************************************************************
* *
* Functions to move to entities.c once the *
* API freeze is smoothen and they can be made public. *
* *
************************************************************************/
#ifdef LIBXML_TREE_ENABLED
/**
* xmlGetEntityFromDtd:
* @dtd: A pointer to the DTD to search
* @name: The entity name
*
* Do an entity lookup in the DTD entity hash table and
* return the corresponding entity, if found.
*
* Returns A pointer to the entity structure or NULL if not found.
*/
static xmlEntityPtr
/* return(xmlGetEntityFromTable(table, name)); */
}
return(NULL);
}
/**
* xmlGetParameterEntityFromDtd:
* @dtd: A pointer to the DTD to search
* @name: The entity name
*
* Do an entity lookup in the DTD pararmeter entity hash table and
* return the corresponding entity, if found.
*
* Returns A pointer to the entity structure or NULL if not found.
*/
static xmlEntityPtr
/* return(xmlGetEntityFromTable(table, name)); */
}
return(NULL);
}
#endif /* LIBXML_TREE_ENABLED */
/************************************************************************
* *
* QName handling helper *
* *
************************************************************************/
/**
* xmlBuildQName:
* @ncname: the Name
* @prefix: the prefix
* @memory: preallocated memory
* @len: preallocated memory length
*
* Builds the QName @prefix:@ncname in @memory if there is enough space
* and prefix is not NULL nor empty, otherwise allocate a new string.
* If prefix is NULL or empty it returns ncname.
*
* Returns the new string which must be freed by the caller if different from
* @memory and @ncname or NULL in case of error
*/
xmlChar *
xmlTreeErrMemory("building QName");
return(NULL);
}
} else {
}
return(ret);
}
/**
* xmlSplitQName2:
* @name: the full QName
* @prefix: a xmlChar **
*
* parse an XML qualified name string
*
* [NS 5] QName ::= (Prefix ':')? LocalPart
*
* [NS 6] Prefix ::= NCName
*
* [NS 7] LocalPart ::= NCName
*
* Returns NULL if not a QName, otherwise the local part, and prefix
* is updated to get the Prefix if any.
*/
xmlChar *
int len = 0;
#ifndef XML_XML_NAMESPACE
/* xml: prefix is not really a namespace */
return(NULL);
#endif
/* nasty but valid */
if (name[0] == ':')
return(NULL);
/*
* we are not trying to validate but just to cut, and yes it will
* work even if this is as set of UTF-8 encoded chars
*/
len++;
return(NULL);
xmlTreeErrMemory("QName split");
return(NULL);
}
xmlTreeErrMemory("QName split");
}
return(NULL);
}
return(ret);
}
/**
* xmlSplitQName3:
* @name: the full QName
* @len: an int *
*
* parse an XML qualified name string,i
*
* returns NULL if it is not a Qualified Name, otherwise, update len
* with the lenght in byte of the prefix and return a pointer
* to the start of the name without the prefix
*/
const xmlChar *
int l = 0;
/* nasty but valid */
if (name[0] == ':')
return(NULL);
/*
* we are not trying to validate but just to cut, and yes it will
* work even if this is as set of UTF-8 encoded chars
*/
l++;
if (name[l] == 0)
return(NULL);
*len = l;
return(&name[l+1]);
}
/************************************************************************
* *
* Check Name, NCName and QName strings *
* *
************************************************************************/
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_DEBUG_ENABLED) || defined (LIBXML_HTML_ENABLED) || defined(LIBXML_SAX1_ENABLED) || defined(LIBXML_HTML_ENABLED) || defined(LIBXML_WRITER_ENABLED) || defined(LIBXML_DOCB_ENABLED)
/**
* xmlValidateNCName:
* @value: the value to check
* @space: allow spaces in front and end of the string
*
* Check that a value conforms to the lexical space of NCName
*
* Returns 0 if this validates, a positive error code number otherwise
* and -1 in case of internal or API error.
*/
int
int c,l;
return(-1);
/*
* First quick algorithm for ASCII range
*/
if (space)
(*cur == '_'))
cur++;
else
goto try_complex;
cur++;
if (space)
if (*cur == 0)
return(0);
/*
* Second check for chars outside the ASCII range
*/
if (space) {
while (IS_BLANK(c)) {
cur += l;
}
}
if ((!IS_LETTER(c)) && (c != '_'))
return(1);
cur += l;
IS_EXTENDER(c)) {
cur += l;
}
if (space) {
while (IS_BLANK(c)) {
cur += l;
}
}
if (c != 0)
return(1);
return(0);
}
#endif
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
/**
* xmlValidateQName:
* @value: the value to check
* @space: allow spaces in front and end of the string
*
* Check that a value conforms to the lexical space of QName
*
* Returns 0 if this validates, a positive error code number otherwise
* and -1 in case of internal or API error.
*/
int
int c,l;
return(-1);
/*
* First quick algorithm for ASCII range
*/
if (space)
(*cur == '_'))
cur++;
else
goto try_complex;
cur++;
if (*cur == ':') {
cur++;
(*cur == '_'))
cur++;
else
goto try_complex;
cur++;
}
if (space)
if (*cur == 0)
return(0);
/*
* Second check for chars outside the ASCII range
*/
if (space) {
while (IS_BLANK(c)) {
cur += l;
}
}
if ((!IS_LETTER(c)) && (c != '_'))
return(1);
cur += l;
IS_EXTENDER(c)) {
cur += l;
}
if (c == ':') {
cur += l;
if ((!IS_LETTER(c)) && (c != '_'))
return(1);
cur += l;
IS_EXTENDER(c)) {
cur += l;
}
}
if (space) {
while (IS_BLANK(c)) {
cur += l;
}
}
if (c != 0)
return(1);
return(0);
}
/**
* xmlValidateName:
* @value: the value to check
* @space: allow spaces in front and end of the string
*
* Check that a value conforms to the lexical space of Name
*
* Returns 0 if this validates, a positive error code number otherwise
* and -1 in case of internal or API error.
*/
int
int c,l;
return(-1);
/*
* First quick algorithm for ASCII range
*/
if (space)
cur++;
else
goto try_complex;
cur++;
if (space)
if (*cur == 0)
return(0);
/*
* Second check for chars outside the ASCII range
*/
if (space) {
while (IS_BLANK(c)) {
cur += l;
}
}
return(1);
cur += l;
cur += l;
}
if (space) {
while (IS_BLANK(c)) {
cur += l;
}
}
if (c != 0)
return(1);
return(0);
}
/**
* xmlValidateNMToken:
* @value: the value to check
* @space: allow spaces in front and end of the string
*
* Check that a value conforms to the lexical space of NMToken
*
* Returns 0 if this validates, a positive error code number otherwise
* and -1 in case of internal or API error.
*/
int
int c,l;
return(-1);
/*
* First quick algorithm for ASCII range
*/
if (space)
cur++;
else
goto try_complex;
cur++;
if (space)
if (*cur == 0)
return(0);
/*
* Second check for chars outside the ASCII range
*/
if (space) {
while (IS_BLANK(c)) {
cur += l;
}
}
return(1);
cur += l;
cur += l;
}
if (space) {
while (IS_BLANK(c)) {
cur += l;
}
}
if (c != 0)
return(1);
return(0);
}
#endif /* LIBXML_TREE_ENABLED */
/************************************************************************
* *
* Allocation and deallocation of basic structures *
* *
************************************************************************/
/**
* xmlSetBufferAllocationScheme:
* @scheme: allocation method to use
*
* Set the buffer allocation method. Types are
* XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
* XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
* improves performance
*/
void
}
/**
* xmlGetBufferAllocationScheme:
*
* Types are
* XML_BUFFER_ALLOC_EXACT - use exact sizes, keeps memory usage down
* XML_BUFFER_ALLOC_DOUBLEIT - double buffer when extra needed,
* improves performance
*
* Returns the current allocation scheme
*/
xmlGetBufferAllocationScheme(void) {
return(xmlBufferAllocScheme);
}
/**
* xmlNewNs:
* @node: the element carrying the namespace
* @href: the URI associated
* @prefix: the prefix for the namespace
*
* Creation of a new Namespace. This function will refuse to create
* a namespace with a similar prefix than an existing one present on this
* node.
* We use href==NULL in the case of an element creation where the namespace
* was not defined.
* Returns a new namespace pointer or NULL
*/
return(NULL);
return(NULL);
/*
* Allocate a new Namespace and fill the fields.
*/
xmlTreeErrMemory("building namespace");
return(NULL);
}
/*
* Add it at the end to preserve parsing order ...
* and checks for existing use of the prefix
*/
} else {
return(NULL);
}
return(NULL);
}
}
}
}
return(cur);
}
/**
* xmlSetNs:
* @node: a node in the document
* @ns: a namespace pointer
*
* Associate a namespace to a node, a posteriori.
*/
void
#ifdef DEBUG_TREE
"xmlSetNs: node == NULL\n");
#endif
return;
}
}
/**
* xmlFreeNs:
* @cur: the namespace pointer
*
* Free up the structures associated to a namespace
*/
void
#ifdef DEBUG_TREE
"xmlFreeNs : ns == NULL\n");
#endif
return;
}
}
/**
* xmlFreeNsList:
* @cur: the first namespace pointer
*
* Free up all the structures associated to the chained namespaces.
*/
void
#ifdef DEBUG_TREE
"xmlFreeNsList : ns == NULL\n");
#endif
return;
}
}
}
/**
* xmlNewDtd:
* @doc: the document pointer
* @name: the DTD name
* @ExternalID: the external ID
* @SystemID: the system ID
*
* Creation of a new DTD for the external subset. To create an
* internal subset, use xmlCreateIntSubset().
*
* Returns a pointer to the new DTD structure
*/
#ifdef DEBUG_TREE
"xmlNewDtd(%s): document %s already have a DTD %s\n",
#endif
return(NULL);
}
/*
* Allocate a new DTD and fill the fields.
*/
xmlTreeErrMemory("building DTD");
return(NULL);
}
if (ExternalID != NULL)
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
/**
* xmlGetIntSubset:
* @doc: the document pointer
*
* Get the internal subset of a document
* Returns a pointer to the DTD structure or NULL if not found
*/
return(NULL);
}
}
/**
* xmlCreateIntSubset:
* @doc: the document pointer
* @name: the DTD name
* @ExternalID: the external (PUBLIC) ID
* @SystemID: the system ID
*
* Create the internal subset of a document
* Returns a pointer to the new DTD structure
*/
#ifdef DEBUG_TREE
"xmlCreateIntSubset(): document %s already have an internal subset\n",
#endif
return(NULL);
}
/*
* Allocate a new DTD and fill the fields.
*/
xmlTreeErrMemory("building internal subset");
return(NULL);
}
xmlTreeErrMemory("building internal subset");
return(NULL);
}
}
if (ExternalID != NULL) {
xmlTreeErrMemory("building internal subset");
return(NULL);
}
}
xmlTreeErrMemory("building internal subset");
return(NULL);
}
}
} else {
} else {
} else {
else
}
}
}
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
/**
* DICT_FREE:
* @str: a string
*
* Free a string if it is not owned by the "dict" dictionnary in the
* current scope
*/
/**
* DICT_COPY:
* @str: a string
*
* Copy a string using a "dict" dictionnary in the current scope,
* if availabe.
*/
if (str) { \
if (dict) { \
else \
} else \
/**
* DICT_CONST_COPY:
* @str: a string
*
* Copy a string using a "dict" dictionnary in the current scope,
* if availabe.
*/
if (str) { \
if (dict) { \
else \
} else \
/**
* xmlFreeDtd:
* @cur: the DTD structure to free up
*
* Free a DTD structure.
*/
void
return;
}
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
/*
* Cleanup all nodes which are not part of the specific lists
* of notations, elements, attributes and entities.
*/
while (c != NULL) {
if ((c->type != XML_NOTATION_NODE) &&
(c->type != XML_ELEMENT_DECL) &&
(c->type != XML_ATTRIBUTE_DECL) &&
(c->type != XML_ENTITY_DECL)) {
xmlUnlinkNode(c);
xmlFreeNode(c);
}
c = next;
}
}
/* TODO !!! */
}
/**
* xmlNewDoc:
* @version: xmlChar string giving the version of XML "1.0"
*
* Creates a new XML document
*
* Returns a new document
*/
/*
* Allocate a new document and fill the fields.
*/
xmlTreeErrMemory("building doc");
return(NULL);
}
xmlTreeErrMemory("building doc");
return(NULL);
}
/*
* The in memory encoding is always UTF8
* This field will never change and would
* be obsolete if not for binary compatibility.
*/
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
/**
* xmlFreeDoc:
* @cur: pointer to the document
*
* Free up all the structures used by a document, tree included.
*/
void
#ifdef DEBUG_TREE
"xmlFreeDoc : document == NULL\n");
#endif
return;
}
#ifdef LIBXML_DEBUG_RUNTIME
#ifdef LIBXML_DEBUG_ENABLED
#endif
#endif
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
/*
* Do this before freeing the children list to avoid ID lookups
*/
}
}
}
/**
* xmlStringLenGetNodeList:
* @doc: the document
* @value: the value of the text
* @len: the length of the string value
*
* Parse the value string and build the node list associated. Should
* produce a flat tree with only TEXTs and ENTITY_REFs.
* Returns a pointer to the first child
*/
const xmlChar *q;
q = cur;
if (cur[0] == '&') {
int charval = 0;
/*
* Save the current text.
*/
if (cur != q) {
} else {
else {
}
}
}
q = cur;
cur += 3;
else
tmp = 0;
else {
NULL);
charval = 0;
break;
}
cur++;
else
tmp = 0;
}
if (tmp == ';')
cur++;
q = cur;
cur += 2;
else
tmp = 0;
else {
NULL);
charval = 0;
break;
}
cur++;
else
tmp = 0;
}
if (tmp == ';')
cur++;
q = cur;
} else {
/*
* Read the entity string
*/
cur++;
q = cur;
(const char *) q);
return(ret);
}
if (cur != q) {
/*
* Predefined entities don't generate nodes
*/
} else
} else {
/*
* Create a new REFERENCE_REF node
*/
return(ret);
}
while (temp) {
}
}
} else {
}
}
}
cur++;
q = cur;
}
if (charval != 0) {
int l;
buf[l] = 0;
} else {
}
}
charval = 0;
}
} else
cur++;
}
/*
* Handle the last piece of text.
*/
} else {
} else {
}
}
}
return(ret);
}
/**
* xmlStringGetNodeList:
* @doc: the document
* @value: the value of the attribute
*
* Parse the value string and build the node list associated. Should
* produce a flat tree with only TEXTs and ENTITY_REFs.
* Returns a pointer to the first child
*/
const xmlChar *q;
q = cur;
while (*cur != 0) {
if (cur[0] == '&') {
int charval = 0;
/*
* Save the current text.
*/
if (cur != q) {
} else {
else {
}
}
}
q = cur;
cur += 3;
else {
NULL);
charval = 0;
break;
}
cur++;
}
if (tmp == ';')
cur++;
q = cur;
cur += 2;
else {
NULL);
charval = 0;
break;
}
cur++;
}
if (tmp == ';')
cur++;
q = cur;
} else {
/*
* Read the entity string
*/
cur++;
q = cur;
if (*cur == 0) {
(xmlNodePtr) doc, (const char *) q);
return(ret);
}
if (cur != q) {
/*
* Predefined entities don't generate nodes
*/
} else
} else {
/*
* Create a new REFERENCE_REF node
*/
return(ret);
}
while (temp) {
}
}
} else {
}
}
}
cur++;
q = cur;
}
if (charval != 0) {
int len;
} else {
}
}
charval = 0;
}
} else
cur++;
}
/*
* Handle the last piece of text.
*/
} else {
} else {
}
}
}
return(ret);
}
/**
* xmlNodeListGetString:
* @doc: the document
* @list: a Node list
* @inLine: should we replace entity contents or show their external form
*
* Build the string equivalent to the text contained in the Node list
* made of TEXTs and ENTITY_REFs
*
* Returns a pointer to the string copy, the caller must free it with xmlFree().
*/
xmlChar *
{
return (NULL);
if (inLine) {
} else {
}
}
if (inLine) {
/* an entity content can be any "well balanced chunk",
* i.e. the result of the content [43] production:
* http://www.w3.org/TR/REC-xml#NT-content.
* So it can contain text, CDATA section or nested
* entity reference nodes (among others).
* -> we recursive call xmlNodeListGetString()
* which handles these types */
}
} else {
}
} else {
buf[0] = '&';
buf[1] = 0;
buf[0] = ';';
buf[1] = 0;
}
}
#if 0
else {
"xmlGetNodeListString : invalid node type %d\n",
}
#endif
}
return (ret);
}
#ifdef LIBXML_TREE_ENABLED
/**
* xmlNodeListGetRawString:
* @doc: the document
* @list: a Node list
* @inLine: should we replace entity contents or show their external form
*
* Builds the string equivalent to the text contained in the Node list
* made of TEXTs and ENTITY_REFs, contrary to xmlNodeListGetString()
* this function doesn't do any character encoding handling.
*
* Returns a pointer to the string copy, the caller must free it with xmlFree().
*/
xmlChar *
{
return (NULL);
if (inLine) {
} else {
}
}
if (inLine) {
/* an entity content can be any "well balanced chunk",
* i.e. the result of the content [43] production:
* http://www.w3.org/TR/REC-xml#NT-content.
* So it can contain text, CDATA section or nested
* entity reference nodes (among others).
* -> we recursive call xmlNodeListGetRawString()
* which handles these types */
buffer =
}
} else {
}
} else {
buf[0] = '&';
buf[1] = 0;
buf[0] = ';';
buf[1] = 0;
}
}
#if 0
else {
"xmlGetNodeListString : invalid node type %d\n",
}
#endif
}
return (ret);
}
#endif /* LIBXML_TREE_ENABLED */
static xmlAttrPtr
int eatname)
{
if (eatname == 1)
return (NULL);
}
/*
* Allocate a new property and fill the fields.
*/
if (eatname == 1)
xmlTreeErrMemory("building attribute");
return (NULL);
}
}
if (eatname == 0) {
else
} else
}
}
/*
* Add it at the end to preserve parsing order ...
*/
} else {
}
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return (cur);
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
defined(LIBXML_SCHEMAS_ENABLED)
/**
* xmlNewProp:
* @node: the holding node
* @name: the name of the attribute
* @value: the value of the attribute
*
* Create a new property carried by a node.
* Returns a pointer to the attribute
*/
#ifdef DEBUG_TREE
"xmlNewProp : name == NULL\n");
#endif
return(NULL);
}
}
#endif /* LIBXML_TREE_ENABLED */
/**
* xmlNewNsProp:
* @node: the holding node
* @ns: the namespace
* @name: the name of the attribute
* @value: the value of the attribute
*
* Create a new property tagged with a namespace and carried by a node.
* Returns a pointer to the attribute
*/
#ifdef DEBUG_TREE
"xmlNewNsProp : name == NULL\n");
#endif
return(NULL);
}
}
/**
* xmlNewNsPropEatName:
* @node: the holding node
* @ns: the namespace
* @name: the name of the attribute
* @value: the value of the attribute
*
* Create a new property tagged with a namespace and carried by a node.
* Returns a pointer to the attribute
*/
#ifdef DEBUG_TREE
"xmlNewNsPropEatName : name == NULL\n");
#endif
return(NULL);
}
}
/**
* xmlNewDocProp:
* @doc: the document
* @name: the name of the attribute
* @value: the value of the attribute
*
* Create a new property carried by a document.
* Returns a pointer to the attribute
*/
#ifdef DEBUG_TREE
"xmlNewDocProp : name == NULL\n");
#endif
return(NULL);
}
/*
* Allocate a new property and fill the fields.
*/
xmlTreeErrMemory("building attribute");
return(NULL);
}
else
}
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
/**
* xmlFreePropList:
* @cur: the first property in the list
*
* Free a property and all its siblings, all the children are freed too.
*/
void
}
}
/**
* xmlFreeProp:
* @cur: an attribute
*
* Free one attribute, all the content is freed too
*/
void
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
/* Check for ID removal -> leading to invalid references ! */
}
}
/**
* xmlRemoveProp:
* @cur: an attribute
*
* Unlink and free one attribute, all the content is freed too
* Note this doesn't work for namespace definition attributes
*
* Returns 0 if success and -1 in case of error.
*/
int
#ifdef DEBUG_TREE
"xmlRemoveProp : cur == NULL\n");
#endif
return(-1);
}
#ifdef DEBUG_TREE
"xmlRemoveProp : cur->parent == NULL\n");
#endif
return(-1);
}
return(0);
}
return(0);
}
}
#ifdef DEBUG_TREE
"xmlRemoveProp : attribute not owned by its node\n");
#endif
return(-1);
}
/**
* xmlNewDocPI:
* @doc: the target document
* @name: the processing instruction name
* @content: the PI content
*
* Creation of a processing instruction element.
* Returns a pointer to the new node object.
*/
#ifdef DEBUG_TREE
"xmlNewPI : name == NULL\n");
#endif
return(NULL);
}
/*
* Allocate a new node and fill the fields.
*/
xmlTreeErrMemory("building PI");
return(NULL);
}
else
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
/**
* xmlNewPI:
* @name: the processing instruction name
* @content: the PI content
*
* Creation of a processing instruction element.
* Use xmlDocNewPI preferably to get string interning
*
* Returns a pointer to the new node object.
*/
}
/**
* xmlNewNode:
* @ns: namespace if any
* @name: the node name
*
* Creation of a new node element. @ns is optional (NULL).
*
* Returns a pointer to the new node object. Uses xmlStrdup() to make
* copy of @name.
*/
#ifdef DEBUG_TREE
"xmlNewNode : name == NULL\n");
#endif
return(NULL);
}
/*
* Allocate a new node and fill the fields.
*/
xmlTreeErrMemory("building node");
return(NULL);
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
/**
* xmlNewNodeEatName:
* @ns: namespace if any
* @name: the node name
*
* Creation of a new node element. @ns is optional (NULL).
*
* Returns a pointer to the new node object, with pointer @name as
* new node's name. Use xmlNewNode() if a copy of @name string is
* is needed as new node's name.
*/
#ifdef DEBUG_TREE
"xmlNewNode : name == NULL\n");
#endif
return(NULL);
}
/*
* Allocate a new node and fill the fields.
*/
xmlTreeErrMemory("building node");
return(NULL);
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
/**
* xmlNewDocNode:
* @doc: the document
* @ns: namespace if any
* @name: the node name
* @content: the XML text content if any
*
* Creation of a new node element within a document. @ns and @content
* are optional (NULL).
* NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
* references, but XML special chars need to be escaped first by using
* xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
* need entities support.
*
* Returns a pointer to the new node object.
*/
else
}
}
return(cur);
}
/**
* xmlNewDocNodeEatName:
* @doc: the document
* @ns: namespace if any
* @name: the node name
* @content: the XML text content if any
*
* Creation of a new node element within a document. @ns and @content
* are optional (NULL).
* NOTE: @content is supposed to be a piece of XML CDATA, so it allow entities
* references, but XML special chars need to be escaped first by using
* xmlEncodeEntitiesReentrant(). Use xmlNewDocRawNode() if you don't
* need entities support.
*
* Returns a pointer to the new node object.
*/
}
}
return(cur);
}
#ifdef LIBXML_TREE_ENABLED
/**
* xmlNewDocRawNode:
* @doc: the document
* @ns: namespace if any
* @name: the node name
* @content: the text content if any
*
* Creation of a new node element within a document. @ns and @content
* are optional (NULL).
*
* Returns a pointer to the new node object.
*/
}
}
return(cur);
}
/**
* xmlNewDocFragment:
* @doc: the document owning the fragment
*
* Creation of a new Fragment node.
* Returns a pointer to the new node object.
*/
/*
* Allocate a new DocumentFragment node and fill the fields.
*/
xmlTreeErrMemory("building fragment");
return(NULL);
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
#endif /* LIBXML_TREE_ENABLED */
/**
* xmlNewText:
* @content: the text content
*
* Creation of a new text node.
* Returns a pointer to the new node object.
*/
/*
* Allocate a new node and fill the fields.
*/
xmlTreeErrMemory("building text");
return(NULL);
}
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
#ifdef LIBXML_TREE_ENABLED
/**
* xmlNewTextChild:
* @parent: the parent node
* @ns: a namespace if any
* @name: the name of the child
* @content: the text content of the child if any.
*
* Creation of a new child element, added at the end of @parent children list.
* @ns and @content parameters are optional (NULL). If @ns is NULL, the newly
* created element inherits the namespace of @parent. If @content is non NULL,
* a child TEXT node will be created containing the string @content.
* NOTE: Use xmlNewChild() if @content will contain entities that need to be
* preserved. Use this function, xmlNewTextChild(), if you need to ensure that
* reserved XML chars that might appear in @content, such as the ampersand,
* greater-than or less-than signs, are automatically replaced by their XML
* escaped entity representations.
*
* Returns a pointer to the new node object.
*/
#ifdef DEBUG_TREE
"xmlNewTextChild : parent == NULL\n");
#endif
return(NULL);
}
#ifdef DEBUG_TREE
"xmlNewTextChild : name == NULL\n");
#endif
return(NULL);
}
/*
* Allocate a new node
*/
else
else
} else {
return(NULL);
}
/*
* add the new element at the end of the children list.
*/
} else {
}
return(cur);
}
#endif /* LIBXML_TREE_ENABLED */
/**
* xmlNewCharRef:
* @doc: the document
* @name: the char ref string, starting with # or "&# ... ;"
*
* Creation of a new character reference node.
* Returns a pointer to the new node object.
*/
return(NULL);
/*
* Allocate a new node and fill the fields.
*/
xmlTreeErrMemory("building character reference");
return(NULL);
}
if (name[0] == '&') {
int len;
name++;
else
} else
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
/**
* xmlNewReference:
* @doc: the document
* @name: the reference name, or the reference string with & and ;
*
* Creation of a new reference node.
* Returns a pointer to the new node object.
*/
return(NULL);
/*
* Allocate a new node and fill the fields.
*/
xmlTreeErrMemory("building reference");
return(NULL);
}
if (name[0] == '&') {
int len;
name++;
else
} else
/*
* The parent pointer in entity is a DTD pointer and thus is NOT
* updated. Not sure if this is 100% correct.
* -George
*/
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
/**
* xmlNewDocText:
* @doc: the document
* @content: the text content
*
* Creation of a new text node within a document.
* Returns a pointer to the new node object.
*/
return(cur);
}
/**
* xmlNewTextLen:
* @content: the text content
* @len: the text len.
*
* Creation of a new text node with an extra parameter for the content's length
* Returns a pointer to the new node object.
*/
/*
* Allocate a new node and fill the fields.
*/
xmlTreeErrMemory("building text");
return(NULL);
}
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
/**
* xmlNewDocTextLen:
* @doc: the document
* @content: the text content
* @len: the text len.
*
* Creation of a new text node with an extra content length parameter. The
* text node pertain to a given document.
* Returns a pointer to the new node object.
*/
return(cur);
}
/**
* xmlNewComment:
* @content: the comment content
*
* Creation of a new node containing a comment.
* Returns a pointer to the new node object.
*/
/*
* Allocate a new node and fill the fields.
*/
xmlTreeErrMemory("building comment");
return(NULL);
}
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
/**
* xmlNewCDataBlock:
* @doc: the document
* @content: the CDATA block content content
* @len: the length of the block
*
* Creation of a new node containing a CDATA block.
* Returns a pointer to the new node object.
*/
/*
* Allocate a new node and fill the fields.
*/
xmlTreeErrMemory("building CDATA");
return(NULL);
}
}
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
return(cur);
}
/**
* xmlNewDocComment:
* @doc: the document
* @content: the comment content
*
* Creation of a new node containing a comment within a document.
* Returns a pointer to the new node object.
*/
return(cur);
}
/**
* xmlSetTreeDoc:
* @tree: the top element
* @doc: the document
*
* update all nodes under the tree to point to the right document
*/
void
return;
}
}
}
}
/**
* xmlSetListDoc:
* @list: the first element
* @doc: the document
*
* update all nodes in the list to point to the right document
*/
void
return;
}
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
/**
* xmlNewChild:
* @parent: the parent node
* @ns: a namespace if any
* @name: the name of the child
* @content: the XML content of the child if any.
*
* Creation of a new child element, added at the end of @parent children list.
* @ns and @content parameters are optional (NULL). If @ns is NULL, the newly
* created element inherits the namespace of @parent. If @content is non NULL,
* a child list containing the TEXTs and ENTITY_REFs node will be created.
* NOTE: @content is supposed to be a piece of XML CDATA, so it allows entity
* references. XML special chars must be escaped first by using
* xmlEncodeEntitiesReentrant(), or xmlNewTextChild() should be used.
*
* Returns a pointer to the new node object.
*/
#ifdef DEBUG_TREE
"xmlNewChild : parent == NULL\n");
#endif
return(NULL);
}
#ifdef DEBUG_TREE
"xmlNewChild : name == NULL\n");
#endif
return(NULL);
}
/*
* Allocate a new node
*/
else
else
} else {
return(NULL);
}
/*
* add the new element at the end of the children list.
*/
} else {
}
return(cur);
}
#endif /* LIBXML_TREE_ENABLED */
/**
* xmlAddPropSibling:
* @prev: the attribute to which @prop is added after
* @cur: the base attribute passed to calling function
* @prop: the new attribute
*
* Add a new attribute after @prev using @cur as base attribute.
* When inserting before @cur, @prev is passed as @cur->prev.
* When inserting after @cur, @prev is passed as @cur.
* If an existing attribute is found it is detroyed prior to adding @prop.
*
* Returns the attribute being inserted or NULL in case of error.
*/
static xmlNodePtr
return(NULL);
/* check if an attribute with the same name exists */
else
}
} else {
}
/* different instance, destroy it (attributes must be unique) */
}
return prop;
}
/**
* xmlAddNextSibling:
* @cur: the child node
* @elem: the new node
*
* Add a new node @elem as the next sibling of @cur
* If the new node was already inserted in a document it is
* first unlinked from its existing context.
* As a result of text merging @elem may be freed.
* If the new node is ATTRIBUTE, it is added into properties instead of children.
* If there is an attribute with equal name, it is first destroyed.
*
* Returns the new node or NULL in case of error.
*/
#ifdef DEBUG_TREE
"xmlAddNextSibling : cur == NULL\n");
#endif
return(NULL);
}
#ifdef DEBUG_TREE
"xmlAddNextSibling : elem == NULL\n");
#endif
return(NULL);
}
#ifdef DEBUG_TREE
"xmlAddNextSibling : cur == elem\n");
#endif
return(NULL);
}
return(cur);
}
}
}
}
return(elem);
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_HTML_ENABLED) || \
defined(LIBXML_SCHEMAS_ENABLED)
/**
* xmlAddPrevSibling:
* @cur: the child node
* @elem: the new node
*
* Add a new node @elem as the previous sibling of @cur
* merging adjacent TEXT nodes (@elem may be freed)
* If the new node was already inserted in a document it is
* first unlinked from its existing context.
* If the new node is ATTRIBUTE, it is added into properties instead of children.
* If there is an attribute with equal name, it is first destroyed.
*
* Returns the new node or NULL in case of error.
*/
#ifdef DEBUG_TREE
"xmlAddPrevSibling : cur == NULL\n");
#endif
return(NULL);
}
#ifdef DEBUG_TREE
"xmlAddPrevSibling : elem == NULL\n");
#endif
return(NULL);
}
#ifdef DEBUG_TREE
"xmlAddPrevSibling : cur == elem\n");
#endif
return(NULL);
}
return(cur);
}
}
}
}
}
return(elem);
}
#endif /* LIBXML_TREE_ENABLED */
/**
* xmlAddSibling:
* @cur: the child node
* @elem: the new node
*
* Add a new element @elem to the list of siblings of @cur
* merging adjacent TEXT nodes (@elem may be freed)
* If the new element was already inserted in a document it is
* first unlinked from its existing context.
*
* Returns the new element or NULL in case of error.
*/
#ifdef DEBUG_TREE
"xmlAddSibling : cur == NULL\n");
#endif
return(NULL);
}
#ifdef DEBUG_TREE
"xmlAddSibling : elem == NULL\n");
#endif
return(NULL);
}
/*
* Constant time is we can rely on the ->parent->last to find
* the last sibling.
*/
} else {
}
return(cur);
}
}
return(elem);
}
/**
* xmlAddChildList:
* @parent: the parent node
* @cur: the first node in the list
*
* Add a list of node at the end of the child list of the parent
* merging adjacent TEXT nodes (@cur may be freed)
*
* Returns the last child or NULL in case of error.
*/
#ifdef DEBUG_TREE
"xmlAddChildList : parent == NULL\n");
#endif
return(NULL);
}
#ifdef DEBUG_TREE
"xmlAddChildList : child == NULL\n");
#endif
return(NULL);
}
#ifdef DEBUG_TREE
"Elements moved to a different document\n");
#endif
}
/*
* add the first element at the end of the children list.
*/
} else {
/*
* If cur and parent->last both are TEXT nodes, then merge them.
*/
/*
* if it's the only child, nothing more to be done.
*/
}
}
}
}
}
return(cur);
}
/**
* xmlAddChild:
* @parent: the parent node
* @cur: the child node
*
* Add a new node to @parent, at the end of the child (or property) list
* merging adjacent TEXT nodes (in which case @cur is freed)
* If the new node is ATTRIBUTE, it is added into properties instead of children.
* If there is an attribute with equal name, it is first destroyed.
*
* Returns the child or NULL in case of error.
*/
#ifdef DEBUG_TREE
"xmlAddChild : parent == NULL\n");
#endif
return(NULL);
}
#ifdef DEBUG_TREE
"xmlAddChild : child == NULL\n");
#endif
return(NULL);
}
#ifdef DEBUG_TREE
"xmlAddChild : parent == cur\n");
#endif
return(NULL);
}
/*
* If cur is a TEXT node, merge its content with adjacent TEXT nodes
* cur is then freed.
*/
return(parent);
}
}
}
/*
* add the new element at the end of the children list.
*/
}
/* this check prevents a loop on tree-traversions if a developer
* tries to add a node to its parent multiple times
*/
return(cur);
/*
* Coalescing
*/
return(parent);
}
return(NULL);
} else {
/* check if an attribute with the same name exists */
else
if ((lastattr != NULL) && (lastattr != (xmlAttrPtr) cur) && (lastattr->type != XML_ATTRIBUTE_DECL)) {
/* different instance, destroy it (attributes must be unique) */
}
return(cur);
/* find the end */
}
}
} else {
} else {
}
}
return(cur);
}
/**
* xmlGetLastChild:
* @parent: the parent node
*
* Search the last child of a node.
* Returns the last child or NULL if none.
*/
#ifdef DEBUG_TREE
"xmlGetLastChild : parent == NULL\n");
#endif
return(NULL);
}
}
/**
* xmlFreeNodeList:
* @cur: the first node in the list
*
* Free a node and all its siblings, this is a recursive behaviour, all
* the children are freed too.
*/
void
return;
}
#ifdef LIBXML_DOCB_ENABLED
#endif
return;
}
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
}
/*
* When a node is a text node or a comment, it uses a global static
* variable for the name of the node.
* Otherwise the node name might come from the document's
* dictionnary
*/
}
}
}
/**
* xmlFreeNode:
* @cur: the node
*
* Free a node, this is a recursive behaviour, all the children are freed too.
* This doesn't unlink the child from the list, use xmlUnlinkNode() first.
*/
void
/* use xmlFreeDtd for DTD nodes */
return;
}
return;
}
return;
}
if ((__xmlRegisterCallbacks) && (xmlDeregisterNodeDefaultValue))
}
/*
* When a node is a text node or a comment, it uses a global static
* variable for the name of the node.
* Otherwise the node name might come from the document's dictionnary
*/
}
/**
* xmlUnlinkNode:
* @cur: the node
*
* Unlink a node from it's current context, the node is not freed
*/
void
#ifdef DEBUG_TREE
"xmlUnlinkNode : node == NULL\n");
#endif
return;
}
}
}
} else {
}
}
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
/**
* xmlReplaceNode:
* @old: the old node
* @cur: the node
*
* Unlink the old node from its current context, prune the new one
* at the same place. If @cur was already inserted in a document it is
* first unlinked from its existing context.
*
* Returns the @old node
*/
#ifdef DEBUG_TREE
"xmlReplaceNode : old == NULL or without parent\n");
#endif
return(NULL);
}
return(old);
}
return(old);
}
#ifdef DEBUG_TREE
"xmlReplaceNode : Trying to replace attribute node with other node type\n");
#endif
return(old);
}
#ifdef DEBUG_TREE
"xmlReplaceNode : Trying to replace a non-attribute node with attribute node\n");
#endif
return(old);
}
} else {
}
}
return(old);
}
#endif /* LIBXML_TREE_ENABLED */
/************************************************************************
* *
* Copy operations *
* *
************************************************************************/
/**
* xmlCopyNamespace:
* @cur: the namespace
*
* Do a copy of the namespace.
*
* Returns: a new #xmlNsPtr, or NULL in case of error.
*/
case XML_LOCAL_NAMESPACE:
break;
default:
#ifdef DEBUG_TREE
#endif
return(NULL);
}
return(ret);
}
/**
* xmlCopyNamespaceList:
* @cur: the first namespace
*
* Do a copy of an namespace list.
*
* Returns: a new #xmlNsPtr, or NULL in case of error.
*/
q = xmlCopyNamespace(cur);
if (p == NULL) {
ret = p = q;
} else {
p->next = q;
p = q;
}
}
return(ret);
}
static xmlNodePtr
static xmlAttrPtr
else
/*
* Humm, we are copying an element whose namespace is defined
* out of the new tree scope. Search it in the original tree
* and add it at the top of the new tree
*/
}
/* correct possibly cycling above the document elt */
}
}
} else {
/*
* we have to find something appropriate here since
* we cant be sure, that the namespce we found is identified
* by the prefix
*/
/* this is the nice case */
} else {
/*
* we are in trouble: we need a new reconcilied namespace.
* This is expensive
*/
}
}
} else
/* tmp->parent = (xmlNodePtr)ret; */
}
}
/*
* Try to handle IDs
*/
}
}
}
return(ret);
}
/**
* xmlCopyProp:
* @target: the element where the attribute will be grafted
* @cur: the attribute
*
* Do a copy of the attribute.
*
* Returns: a new #xmlAttrPtr, or NULL in case of error.
*/
}
/**
* xmlCopyPropList:
* @target: the element where the attributes will be grafted
* @cur: the first attribute
*
* Do a copy of an attribute list.
*
* Returns: a new #xmlAttrPtr, or NULL in case of error.
*/
xmlAttrPtr p = NULL,q;
if (q == NULL)
return(NULL);
if (p == NULL) {
ret = p = q;
} else {
p->next = q;
q->prev = p;
p = q;
}
}
return(ret);
}
/*
* NOTE about the CopyNode operations !
*
* They are split into external and internal parts for one
* tricky reason: namespaces. Doing a direct copy of a node
* say RPM:Copyright without changing the namespace pointer to
* something else can produce stale links. One way to do it is
* to keep a reference counter but this doesn't work as soon
* as one move the element or the subtree out of the scope of
* the existing namespace. The actual solution seems to add
* a copy of the namespace at the top of the copied tree if
* not available in the subtree.
* Hence two functions, the public front-end call the inner ones
* The argument "recursive" normally indicates a recursive copy
* of the node with values 0 (no) and 1 (yes). For XInclude,
* however, we allow a value of 2 to indicate copy properties and
* namespace info, but don't recurse on children.
*/
static xmlNodePtr
int extended) {
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_ELEMENT_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
break;
case XML_ATTRIBUTE_NODE:
case XML_NAMESPACE_DECL:
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
#ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE:
#endif
#ifdef LIBXML_TREE_ENABLED
#endif /* LIBXML_TREE_ENABLED */
case XML_DOCUMENT_TYPE_NODE:
case XML_NOTATION_NODE:
case XML_DTD_NODE:
case XML_ELEMENT_DECL:
case XML_ATTRIBUTE_DECL:
case XML_ENTITY_DECL:
return(NULL);
}
/*
* Allocate a new node and fill the fields.
*/
xmlTreeErrMemory("copying node");
return(NULL);
}
else
}
}else{
}
/*
* this is a tricky part for the node register thing:
* in case ret does get coalesced in xmlAddChild
* the deregister-node callback is called; so we register ret now already
*/
if ((__xmlRegisterCallbacks) && (xmlRegisterNodeDefaultValue))
/* node could have coalesced */
return(tmp);
}
if (!extended)
goto out;
/*
* Humm, we are copying an element whose namespace is defined
* out of the new tree scope. Search it in the original tree
* and add it at the top of the new tree
*/
}
} else {
/*
* reference the existing namespace definition in our own tree.
*/
}
}
/*
* The copied node will go into a separate document, so
* to avoid dangling references to the ENTITY_DECL node
* we cannot keep the reference. Try to find it in the
* target document.
*/
} else {
}
}
out:
/* if parent != NULL we already registered the node above */
return(ret);
}
static xmlNodePtr
xmlNodePtr p = NULL,q;
#ifdef LIBXML_TREE_ENABLED
continue;
}
xmlAddChild(parent, q);
} else {
xmlAddChild(parent, q);
}
} else
#endif /* LIBXML_TREE_ENABLED */
ret = p = q;
} else if (p != q) {
/* the test is required if xmlStaticCopyNode coalesced 2 text nodes */
p->next = q;
q->prev = p;
p = q;
}
}
return(ret);
}
/**
* xmlCopyNode:
* @node: the node
* @extended: if 1 do a recursive copy (properties, namespaces and children
* when applicable)
* if 2 copy properties and namespaces (when applicable)
*
* Do a copy of the node.
*
* Returns: a new #xmlNodePtr, or NULL in case of error.
*/
return(ret);
}
/**
* xmlDocCopyNode:
* @node: the node
* @doc: the document
* @extended: if 1 do a recursive copy (properties, namespaces and children
* when applicable)
* if 2 copy properties and namespaces (when applicable)
*
* Do a copy of the node to a given document.
*
* Returns: a new #xmlNodePtr, or NULL in case of error.
*/
return(ret);
}
/**
* xmlDocCopyNodeList:
* @doc: the target document
* @node: the first node in the list.
*
* Do a recursive copy of the node list.
*
* Returns: a new #xmlNodePtr, or NULL in case of error.
*/
return(ret);
}
/**
* xmlCopyNodeList:
* @node: the first node in the list.
*
* Do a recursive copy of the node list.
* Use xmlDocCopyNodeList() if possible to ensure string interning.
*
* Returns: a new #xmlNodePtr, or NULL in case of error.
*/
return(ret);
}
#if defined(LIBXML_TREE_ENABLED)
/**
* xmlCopyDtd:
* @dtd: the dtd
*
* Do a copy of the dtd.
*
* Returns: a new #xmlDtdPtr, or NULL in case of error.
*/
q = NULL;
break;
q = (xmlNodePtr)
break;
break;
}
q = (xmlNodePtr)
q = (xmlNodePtr)
q = xmlCopyNode(cur, 0);
}
if (q == NULL) {
continue;
}
if (p == NULL)
else
p->next = q;
q->prev = p;
p = q;
}
return(ret);
}
#endif
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
/**
* xmlCopyDoc:
* @doc: the document
* @recursive: if not zero do a recursive copy.
*
* Do a copy of the document info. If recursive, the content tree will
* be copied too as well as DTD, namespaces and entities.
*
* Returns: a new #xmlDocPtr, or NULL in case of error.
*/
#ifdef LIBXML_TREE_ENABLED
}
#endif
(xmlNodePtr)ret);
}
}
return(ret);
}
#endif /* LIBXML_TREE_ENABLED */
/************************************************************************
* *
* Content access functions *
* *
************************************************************************/
/**
* xmlGetLineNo:
* @node: valid node
*
* Get line number of @node. This requires activation of this option
* before invoking the parser by calling xmlLineNumbersDefault(1)
*
* Returns the line number if successful, -1 otherwise
*/
long
{
long result = -1;
if (!node)
return result;
return result;
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_DEBUG_ENABLED)
/**
* xmlGetNodePath:
* @node: a node
*
* Build a structure based Path for the given node
*
* Returns the new path or NULL in case of error. The caller must free
* the returned string
*/
xmlChar *
{
const char *sep;
const char *name;
char nametemp[100];
return (NULL);
buf_len = 500;
xmlTreeErrMemory("getting node path");
return (NULL);
}
xmlTreeErrMemory("getting node path");
return (NULL);
}
buffer[0] = 0;
do {
name = "";
sep = "?";
occur = 0;
if (buffer[0] == '/')
break;
sep = "/";
generic = 0;
sep = "/";
} else {
/*
* We cannot express named elements in the default
* namespace, so use "*".
*/
generic = 1;
name = "*";
}
}
/*
* Thumbler index computation
* TODO: the ocurence test seems bogus for namespaced names
*/
(generic ||
occur++;
}
if (occur == 0) {
(generic ||
occur++;
}
if (occur != 0)
occur = 1;
} else
occur++;
sep = "/";
name = "comment()";
/*
* Thumbler index computation
*/
occur++;
}
if (occur == 0) {
occur++;
}
if (occur != 0)
occur = 1;
} else
occur++;
sep = "/";
name = "text()";
/*
* Thumbler index computation
*/
occur++;
}
/*
* Evaluate if this is the only text- or CDATA-section-node;
* if yes, then we'll get "text()", otherwise "text()[1]".
*/
if (occur == 0) {
{
occur = 1;
break;
}
}
} else
occur++;
sep = "/";
/*
* Thumbler index computation
*/
occur++;
}
if (occur == 0) {
occur++;
}
if (occur != 0)
occur = 1;
} else
occur++;
sep = "/@";
else
}
} else {
}
/*
* Make sure there is enough room
*/
buf_len =
xmlTreeErrMemory("getting node path");
return (NULL);
}
xmlTreeErrMemory("getting node path");
return (NULL);
}
}
if (occur == 0)
else
return (buffer);
}
#endif /* LIBXML_TREE_ENABLED */
/**
* xmlDocGetRootElement:
* @doc: the document
*
* Get the root element of the document (doc->children is a list
* containing possibly comments, PIs, etc ...).
*
* Returns the #xmlNodePtr for the root or NULL
*/
return(ret);
}
return(ret);
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_WRITER_ENABLED)
/**
* xmlDocSetRootElement:
* @doc: the document
* @root: the new document root element, if root is NULL no action is taken,
* to remove a node from a document use xmlUnlinkNode(root) instead.
*
* Set the root element of the document (doc->children is a list
* containing possibly comments, PIs, etc ...).
*
* Returns the old root element if any was found, NULL if root was NULL
*/
return(NULL);
break;
}
} else {
}
} else {
}
return(old);
}
#endif
#if defined(LIBXML_TREE_ENABLED)
/**
* xmlNodeSetLang:
* @cur: the node being changed
* @lang: the language description
*
* Set the language of a node, i.e. the values of the xml:lang
* attribute.
*/
void
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_COMMENT_NODE:
case XML_DOCUMENT_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_NOTATION_NODE:
case XML_HTML_DOCUMENT_NODE:
case XML_DTD_NODE:
case XML_ELEMENT_DECL:
case XML_ATTRIBUTE_DECL:
case XML_ENTITY_DECL:
case XML_PI_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
case XML_NAMESPACE_DECL:
#ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE:
#endif
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
return;
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
break;
}
return;
}
#endif /* LIBXML_TREE_ENABLED */
/**
* xmlNodeGetLang:
* @cur: the node being checked
*
* Searches the language of a node, i.e. the values of the xml:lang
* attribute or the one carried by the nearest ancestor.
*
* Returns a pointer to the lang value, or NULL if not found
* It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
return(lang);
}
return(NULL);
}
#ifdef LIBXML_TREE_ENABLED
/**
* xmlNodeSetSpacePreserve:
* @cur: the node being changed
* @val: the xml:space value ("0": default, 1: "preserve")
*
* Set (or reset) the space preserving behaviour of a node, i.e. the
* value of the xml:space attribute.
*/
void
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_COMMENT_NODE:
case XML_DOCUMENT_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_NOTATION_NODE:
case XML_HTML_DOCUMENT_NODE:
case XML_DTD_NODE:
case XML_ELEMENT_DECL:
case XML_ATTRIBUTE_DECL:
case XML_ENTITY_DECL:
case XML_PI_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
case XML_NAMESPACE_DECL:
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
#ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE:
#endif
return;
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
break;
}
return;
switch (val) {
case 0:
break;
case 1:
break;
}
}
#endif /* LIBXML_TREE_ENABLED */
/**
* xmlNodeGetSpacePreserve:
* @cur: the node being checked
*
* Searches the space preserving behaviour of a node, i.e. the values
* of the xml:space attribute or the one carried by the nearest
* ancestor.
*
* Returns -1 if xml:space is not inherited, 0 if "default", 1 if "preserve"
*/
int
return(1);
}
return(0);
}
}
}
return(-1);
}
#ifdef LIBXML_TREE_ENABLED
/**
* xmlNodeSetName:
* @cur: the node being changed
* @name: the new tag name
*
* Set (or reset) the name of a node.
*/
void
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_COMMENT_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_NOTATION_NODE:
case XML_HTML_DOCUMENT_NODE:
case XML_NAMESPACE_DECL:
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
#ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE:
#endif
return;
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
case XML_PI_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
case XML_DTD_NODE:
case XML_DOCUMENT_NODE:
case XML_ELEMENT_DECL:
case XML_ATTRIBUTE_DECL:
case XML_ENTITY_DECL:
break;
}
else
} else {
}
}
#endif
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED)
/**
* xmlNodeSetBase:
* @cur: the node being changed
* @uri: the new base URI
*
* Set (or reset) the base URI of a node, i.e. the value of the
* xml:base attribute.
*/
void
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_COMMENT_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_NOTATION_NODE:
case XML_DTD_NODE:
case XML_ELEMENT_DECL:
case XML_ATTRIBUTE_DECL:
case XML_ENTITY_DECL:
case XML_PI_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
case XML_NAMESPACE_DECL:
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
return;
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
break;
case XML_DOCUMENT_NODE:
#ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE:
#endif
case XML_HTML_DOCUMENT_NODE: {
else
return;
}
}
return;
} else {
}
}
#endif /* LIBXML_TREE_ENABLED */
/**
* xmlNodeGetBase:
* @doc: the document the node pertains to
* @cur: the node being checked
*
* Searches for the BASE URL. The code should work on both XML
* 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
* It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
return(NULL);
continue;
}
continue;
}
continue;
}
}
}
return(NULL);
}
}
} else {
return(NULL);
}
} else {
}
return(oldbase);
}
}
}
return(newbase);
}
return(oldbase);
}
/**
* xmlNodeBufGetContent:
* @buffer: a buffer
* @cur: the node being read
*
* Read the value of a node @cur, this can be either the text carried
* directly by this node if it's a TEXT node or the aggregate string
* of the values carried by this node child's (TEXT and ENTITY_REF).
* Entity references are substituted.
* Fills up the buffer @buffer with this value
*
* Returns 0 in case of success and -1 in case of error.
*/
int
{
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
break;
case XML_DOCUMENT_FRAG_NODE:
case XML_ELEMENT_NODE:{
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
break;
case XML_ENTITY_REF_NODE:
break;
default:
break;
}
/*
* Skip to next node
*/
continue;
}
}
break;
continue;
}
do {
break;
break;
}
break;
}
}
break;
}
case XML_ATTRIBUTE_NODE:{
else
}
break;
}
case XML_COMMENT_NODE:
case XML_PI_NODE:
break;
case XML_ENTITY_REF_NODE:{
/* lookup entity declaration */
return(-1);
/* an entity content can be any "well balanced chunk",
* i.e. the result of the content [43] production:
* http://www.w3.org/TR/REC-xml#NT-content
* -> we iterate through child nodes and recursive call
* xmlNodeGetContent() which handles all possible node types */
while (tmp) {
}
break;
}
case XML_ENTITY_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_NOTATION_NODE:
case XML_DTD_NODE:
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
break;
case XML_DOCUMENT_NODE:
#ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE:
#endif
case XML_HTML_DOCUMENT_NODE:
}
}
break;
case XML_NAMESPACE_DECL:
break;
case XML_ELEMENT_DECL:
case XML_ATTRIBUTE_DECL:
case XML_ENTITY_DECL:
break;
}
return(0);
}
/**
* xmlNodeGetContent:
* @cur: the node being read
*
* Read the value of a node, this can be either the text carried
* directly by this node if it's a TEXT node or the aggregate string
* of the values carried by this node child's (TEXT and ENTITY_REF).
* Entity references are substituted.
* Returns a new #xmlChar * or NULL if no content is available.
* It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
{
return (NULL);
case XML_DOCUMENT_FRAG_NODE:
case XML_ELEMENT_NODE:{
return (NULL);
return (ret);
}
case XML_ATTRIBUTE_NODE:
case XML_COMMENT_NODE:
case XML_PI_NODE:
return (NULL);
case XML_ENTITY_REF_NODE:{
/* lookup entity declaration */
return (NULL);
buffer = xmlBufferCreate();
return (NULL);
return (ret);
}
case XML_ENTITY_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_NOTATION_NODE:
case XML_DTD_NODE:
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
return (NULL);
case XML_DOCUMENT_NODE:
#ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE:
#endif
case XML_HTML_DOCUMENT_NODE: {
buffer = xmlBufferCreate();
return (NULL);
return (ret);
}
case XML_NAMESPACE_DECL: {
return (tmp);
}
case XML_ELEMENT_DECL:
/* TODO !!! */
return (NULL);
case XML_ATTRIBUTE_DECL:
/* TODO !!! */
return (NULL);
case XML_ENTITY_DECL:
/* TODO !!! */
return (NULL);
case XML_CDATA_SECTION_NODE:
case XML_TEXT_NODE:
return (NULL);
}
return (NULL);
}
/**
* xmlNodeSetContent:
* @cur: the node being modified
* @content: the new value of the content
*
* Replace the content of a node.
* NOTE: @content is supposed to be a piece of XML CDATA, so it allows entity
* references, but XML special chars need to be escaped first by using
* xmlEncodeEntitiesReentrant() resp. xmlEncodeSpecialChars().
*/
void
#ifdef DEBUG_TREE
"xmlNodeSetContent : node == NULL\n");
#endif
return;
}
case XML_DOCUMENT_FRAG_NODE:
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
break;
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
}
} else
break;
case XML_DOCUMENT_NODE:
case XML_HTML_DOCUMENT_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
#ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE:
#endif
break;
case XML_NOTATION_NODE:
break;
case XML_DTD_NODE:
break;
case XML_NAMESPACE_DECL:
break;
case XML_ELEMENT_DECL:
/* TODO !!! */
break;
case XML_ATTRIBUTE_DECL:
/* TODO !!! */
break;
case XML_ENTITY_DECL:
/* TODO !!! */
break;
}
}
#ifdef LIBXML_TREE_ENABLED
/**
* xmlNodeSetContentLen:
* @cur: the node being modified
* @content: the new value of the content
* @len: the size of @content
*
* Replace the content of a node.
* NOTE: @content is supposed to be a piece of XML CDATA, so it allows entity
* references, but XML special chars need to be escaped first by using
* xmlEncodeEntitiesReentrant() resp. xmlEncodeSpecialChars().
*/
void
#ifdef DEBUG_TREE
"xmlNodeSetContentLen : node == NULL\n");
#endif
return;
}
case XML_DOCUMENT_FRAG_NODE:
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
break;
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
case XML_NOTATION_NODE:
}
} else
break;
case XML_DOCUMENT_NODE:
case XML_DTD_NODE:
case XML_HTML_DOCUMENT_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_NAMESPACE_DECL:
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
#ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE:
#endif
break;
case XML_ELEMENT_DECL:
/* TODO !!! */
break;
case XML_ATTRIBUTE_DECL:
/* TODO !!! */
break;
case XML_ENTITY_DECL:
/* TODO !!! */
break;
}
}
#endif /* LIBXML_TREE_ENABLED */
/**
* xmlNodeAddContentLen:
* @cur: the node being modified
* @content: extra content
* @len: the size of @content
*
* Append the extra substring to the node content.
* NOTE: In contrast to xmlNodeSetContentLen(), @content is supposed to be
* raw text, so unescaped XML special chars are allowed, entity
* references are not supported.
*/
void
#ifdef DEBUG_TREE
"xmlNodeAddContentLen : node == NULL\n");
#endif
return;
}
if (len <= 0) return;
case XML_DOCUMENT_FRAG_NODE:
case XML_ELEMENT_NODE: {
return;
}
}
break;
}
case XML_ATTRIBUTE_NODE:
break;
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
case XML_NOTATION_NODE:
break;
}
}
case XML_DOCUMENT_NODE:
case XML_DTD_NODE:
case XML_HTML_DOCUMENT_NODE:
case XML_DOCUMENT_TYPE_NODE:
case XML_NAMESPACE_DECL:
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
#ifdef LIBXML_DOCB_ENABLED
case XML_DOCB_DOCUMENT_NODE:
#endif
break;
case XML_ELEMENT_DECL:
case XML_ATTRIBUTE_DECL:
case XML_ENTITY_DECL:
break;
}
}
/**
* xmlNodeAddContent:
* @cur: the node being modified
* @content: extra content
*
* Append the extra substring to the node content.
* NOTE: In contrast to xmlNodeSetContent(), @content is supposed to be
* raw text, so unescaped XML special chars are allowed, entity
* references are not supported.
*/
void
int len;
#ifdef DEBUG_TREE
"xmlNodeAddContent : node == NULL\n");
#endif
return;
}
}
/**
* xmlTextMerge:
* @first: the first text node
* @second: the second text node being merged
*
* Merge two text nodes into one
* Returns the first text node augmented
*/
return(first);
return(first);
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XPATH_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
/**
* xmlGetNsList:
* @doc: the document
* @node: the current node
*
* Search all the namespace applying to a given element.
* Returns an NULL terminated array of all the #xmlNsPtr found
* that need to be freed by the caller or NULL if no
* namespace if defined
*/
xmlNsPtr *
{
int nbns = 0;
int maxns = 10;
int i;
ret =
sizeof(xmlNsPtr));
xmlTreeErrMemory("getting namespace list");
return (NULL);
}
}
for (i = 0; i < nbns; i++) {
break;
}
if (i >= nbns) {
maxns *= 2;
(maxns +
1) *
sizeof(xmlNsPtr));
xmlTreeErrMemory("getting namespace list");
return (NULL);
}
}
}
}
}
}
return (ret);
}
#endif /* LIBXML_TREE_ENABLED */
/*
* xmlTreeEnsureXMLDecl:
* @doc: the doc
*
* Ensures that there is an XML namespace declaration on the doc.
*
* Returns the XML ns-struct or NULL on API and internal errors.
*/
static xmlNsPtr
{
return (NULL);
{
"allocating the XML namespace");
return (NULL);
}
return (ns);
}
}
/**
* xmlSearchNs:
* @doc: the document
* @node: the current node
* @nameSpace: the namespace prefix
*
* Search a Ns registered under a given name space for a document.
* recurse on the parents until it finds the defined namespace
* or return NULL otherwise.
* @nameSpace can be NULL, this is a search for the default namespace.
* We don't allow to cross entities boundaries. If you don't declare
* the namespace within those you will be in troubles !!! A warning
* is generated to cover this case.
*
* Returns the namespace pointer or NULL.
*/
/*
* The XML-1.0 namespace is normally held on the root
* element. In this case exceptionally create it on the
* node element.
*/
xmlTreeErrMemory("searching namespace");
return(NULL);
}
return(cur);
}
return(NULL);
}
/*
* Return the XML namespace declaration held by the doc.
*/
return(xmlTreeEnsureXMLDecl(doc));
else
}
return(NULL);
return(cur);
return(cur);
}
return(cur);
return(cur);
}
}
}
}
return(NULL);
}
/**
* xmlNsInScope:
* @doc: the document
* @node: the current node
* @ancestor: the ancestor carrying the namespace
* @prefix: the namespace prefix
*
* Verify that the given namespace held on @ancestor is still in scope
* on node.
*
* Returns 1 if true, 0 if false and -1 in case of error.
*/
static int
{
return (-1);
return (0);
return (0);
}
}
}
return (-1);
return (1);
}
/**
* xmlSearchNsByHref:
* @doc: the document
* @node: the current node
* @href: the namespace value
*
* Search a Ns aliasing a given URI. Recurse on the parents until it finds
* the defined namespace or return NULL otherwise.
* Returns the namespace pointer or NULL.
*/
{
int is_attr;
return (NULL);
/*
* Only the document can hold the XML spec namespace.
*/
/*
* The XML-1.0 namespace is normally held on the root
* element. In this case exceptionally create it on the
* node element.
*/
xmlTreeErrMemory("searching namespace");
return (NULL);
}
return (cur);
}
return(NULL);
}
/*
* Return the XML namespace declaration held by the doc.
*/
return(xmlTreeEnsureXMLDecl(doc));
else
}
return (NULL);
return (cur);
}
}
return (cur);
}
}
}
}
}
return (NULL);
}
/**
* xmlNewReconciliedNs:
* @doc: the document
* @tree: a node expected to hold the new namespace
* @ns: the original namespace
*
* This function tries to locate a namespace definition in a tree
* ancestors, or create a new namespace definition node similar to
* @ns trying to reuse the same prefix. However if the given prefix is
* null (default namespace) or reused within the subtree defined by
* @tree or on one of its ancestors then a new prefix is generated.
* Returns the (new) namespace definition or NULL in case of error
*/
int counter = 1;
#ifdef DEBUG_TREE
"xmlNewReconciliedNs : tree == NULL\n");
#endif
return(NULL);
}
#ifdef DEBUG_TREE
"xmlNewReconciliedNs : ns == NULL\n");
#endif
return(NULL);
}
/*
* Search an existing namespace definition inherited.
*/
return(def);
/*
* Find a close prefix which is not already in use.
* Let's strip namespace prefixes longer than 20 chars !
*/
else
else
}
/*
* OK, now we are ready to create a new one.
*/
return(def);
}
#ifdef LIBXML_TREE_ENABLED
/**
* xmlReconciliateNs:
* @doc: the document
* @tree: a node defining the subtree to reconciliate
*
* This function checks that all the namespaces declared within the given
* tree are properly declared. This is needed for example after Copy or Cut
* and then paste operations. The subtree may still hold pointers to
* as possible the function try to reuse the existing namespaces found in
* the new environment. If not possible the new namespaces are redeclared
* on @tree at the top of the given subtree.
* Returns the number of namespace declarations created or -1 in case of error.
*/
int
int sizeCache = 0;
int nbCache = 0;
xmlNsPtr n;
int ret = 0, i;
/*
* Reconciliate the node namespace
*/
/*
* initialize the cache if needed
*/
if (sizeCache == 0) {
sizeCache = 10;
sizeof(xmlNsPtr));
xmlTreeErrMemory("fixing namespaces");
return(-1);
}
sizeof(xmlNsPtr));
xmlTreeErrMemory("fixing namespaces");
return(-1);
}
}
for (i = 0;i < nbCache;i++) {
break;
}
}
if (i == nbCache) {
/*
* OK we need to recreate a new namespace definition
*/
if (n != NULL) { /* :-( what if else ??? */
/*
* check if we need to grow the cache buffers.
*/
sizeCache *= 2;
sizeof(xmlNsPtr));
xmlTreeErrMemory("fixing namespaces");
return(-1);
}
sizeof(xmlNsPtr));
xmlTreeErrMemory("fixing namespaces");
return(-1);
}
}
}
}
}
/*
* now check for namespace hold by attributes on the node.
*/
/*
* initialize the cache if needed
*/
if (sizeCache == 0) {
sizeCache = 10;
sizeof(xmlNsPtr));
xmlTreeErrMemory("fixing namespaces");
return(-1);
}
sizeof(xmlNsPtr));
xmlTreeErrMemory("fixing namespaces");
return(-1);
}
}
for (i = 0;i < nbCache;i++) {
break;
}
}
if (i == nbCache) {
/*
* OK we need to recreate a new namespace definition
*/
if (n != NULL) { /* :-( what if else ??? */
/*
* check if we need to grow the cache buffers.
*/
sizeCache *= 2;
xmlTreeErrMemory("fixing namespaces");
return(-1);
}
xmlTreeErrMemory("fixing namespaces");
return(-1);
}
}
}
}
}
}
}
/*
* Browse the full subtree, deep first
*/
/* deep first */
/* then siblings */
/* go up to parents->next if needed */
break;
}
break;
}
}
/* exit condition */
} else
break;
}
return(ret);
}
#endif /* LIBXML_TREE_ENABLED */
static xmlAttrPtr
{
return(NULL);
/*
* We want the attr to be in no namespace.
*/
do {
return(prop);
}
} else {
/*
* We want the attr to be in the specified namespace.
*/
do {
{
return(prop);
}
}
}
#ifdef LIBXML_TREE_ENABLED
if (! useDTD)
return(NULL);
/*
* the internal or external subset.
*/
/*
* We need the QName of the element for the DTD-lookup.
*/
return(NULL);
} else
/*
* The common and nice case: Attr in no namespace.
*/
}
} else {
/*
* The ugly case: Search using the prefixes of in-scope
* ns-decls corresponding to @nsName.
*/
return(NULL);
}
if (attrDecl)
break;
if (attrDecl)
break;
}
}
cur++;
}
}
/*
*/
return((xmlAttrPtr) attrDecl);
}
#endif /* LIBXML_TREE_ENABLED */
return(NULL);
}
static xmlChar*
{
return(NULL);
/*
* Note that we return at least the empty string.
* TODO: Do we really always want that?
*/
{
/*
* Optimization for the common case: only 1 text node.
*/
} else {
return(ret);
}
}
}
return(NULL);
}
/**
* xmlHasProp:
* @node: the node
* @name: the attribute name
*
* Search an attribute associated to a node
* This function also looks in DTD attribute declaration for #FIXED or
* default declaration values unless DTD use has been turned off.
*
* Returns the attribute or the attribute declaration or NULL if
* neither was found.
*/
return(NULL);
/*
* Check on the properties attached to the node
*/
return(prop);
}
}
if (!xmlCheckDTD) return(NULL);
/*
* Check if there is a default declaration in the internal
* or external subsets
*/
/* return attribute declaration only if a default value is given
(that includes #FIXED declarations) */
return((xmlAttrPtr) attrDecl);
}
}
return(NULL);
}
/**
* xmlHasNsProp:
* @node: the node
* @name: the attribute name
* @nameSpace: the URI of the namespace
*
* Search for an attribute associated to a node
* This attribute has to be anchored in the namespace specified.
* This does the entity substitution.
* This function looks in DTD attribute declaration for #FIXED or
* default declaration values unless DTD use has been turned off.
* Note that a namespace of NULL indicates to use the default namespace.
*
* Returns the attribute or the attribute declaration or NULL
* if neither was found.
*/
}
/**
* xmlGetProp:
* @node: the node
* @name: the attribute name
*
* Search and get the value of an attribute associated to a node
* This does the entity substitution.
* This function looks in DTD attribute declaration for #FIXED or
* default declaration values unless DTD use has been turned off.
* NOTE: this function acts independently of namespaces associated
* to the attribute. Use xmlGetNsProp() or xmlGetNoNsProp()
* for namespace aware processing.
*
* Returns the attribute value or NULL if not found.
* It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
return(NULL);
return(xmlGetPropNodeValueInternal(prop));
}
/**
* xmlGetNoNsProp:
* @node: the node
* @name: the attribute name
*
* Search and get the value of an attribute associated to a node
* This does the entity substitution.
* This function looks in DTD attribute declaration for #FIXED or
* default declaration values unless DTD use has been turned off.
* This function is similar to xmlGetProp except it will accept only
* an attribute in no namespace.
*
* Returns the attribute value or NULL if not found.
* It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
return(NULL);
return(xmlGetPropNodeValueInternal(prop));
}
/**
* xmlGetNsProp:
* @node: the node
* @name: the attribute name
* @nameSpace: the URI of the namespace
*
* Search and get the value of an attribute associated to a node
* This attribute has to be anchored in the namespace specified.
* This does the entity substitution.
* This function looks in DTD attribute declaration for #FIXED or
* default declaration values unless DTD use has been turned off.
*
* Returns the attribute value or NULL if not found.
* It's up to the caller to free the memory with xmlFree().
*/
xmlChar *
return(NULL);
return(xmlGetPropNodeValueInternal(prop));
}
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED)
/**
* xmlUnsetProp:
* @node: the node
* @name: the attribute name
*
* Remove an attribute carried by a node.
* This handles only attributes in no namespace.
* Returns 0 if successful, -1 if not found
*/
int
return(-1);
return(0);
}
/**
* xmlUnsetNsProp:
* @node: the node
* @ns: the namespace definition
* @name: the attribute name
*
* Remove an attribute carried by a node.
* Returns 0 if successful, -1 if not found
*/
int
return(-1);
return(0);
}
#endif
#if defined(LIBXML_TREE_ENABLED) || defined(LIBXML_XINCLUDE_ENABLED) || defined(LIBXML_SCHEMAS_ENABLED) || defined(LIBXML_HTML_ENABLED)
/**
* xmlSetProp:
* @node: the node
* @name: the attribute name (a QName)
* @value: the attribute value
*
* Set (or reset) an attribute carried by a node.
* If @name has a prefix, then the corresponding
* namespace-binding will be used, if in scope; it is an
* error it there's no such ns-binding for the prefix in
* scope.
* Returns the attribute pointer.
*
*/
int len;
return(NULL);
/*
* handle QNames
*/
}
}
/**
* xmlSetNsProp:
* @node: the node
* @ns: the namespace definition
* @name: the attribute name
* @value: the attribute value
*
* Set (or reset) an attribute carried by a node.
* The ns structure must be in scope, this is not checked
*
* Returns the attribute pointer.
*/
{
return(NULL);
/*
* Modify the attribute's value.
*/
}
}
}
return(prop);
}
/*
* No equal attr found; create a new one.
*/
}
#endif /* LIBXML_TREE_ENABLED */
/**
* xmlNodeIsText:
* @node: the node
*
* Is this node a Text node ?
* Returns 1 yes, 0 no
*/
int
return(0);
}
/**
* xmlIsBlankNode:
* @node: the node
*
* Checks whether this node is an empty or whitespace only
* (and possibly ignorable) text-node.
*
* Returns 1 yes, 0 no
*/
int
return(0);
while (*cur != 0) {
if (!IS_BLANK_CH(*cur)) return(0);
cur++;
}
return(1);
}
/**
* xmlTextConcat:
* @node: the node
* @content: the content
* @len: @content length
*
* Concat the given string at the end of the existing node content
*
* Returns -1 in case of error, 0 otherwise
*/
int
#ifdef DEBUG_TREE
"xmlTextConcat: node is not text nor CDATA\n");
#endif
return(-1);
}
/* need to check if content is currently in the dictionary */
} else {
}
return(-1);
return(0);
}
/************************************************************************
* *
* Output : to a FILE or in memory *
* *
************************************************************************/
/**
* xmlBufferCreate:
*
* routine to create an XML buffer.
* returns the new structure.
*/
xmlBufferCreate(void) {
xmlTreeErrMemory("creating buffer");
return(NULL);
}
xmlTreeErrMemory("creating buffer");
return(NULL);
}
return(ret);
}
/**
* xmlBufferCreateSize:
* @size: initial size of buffer
*
* routine to create an XML buffer.
* returns the new structure.
*/
xmlTreeErrMemory("creating buffer");
return(NULL);
}
xmlTreeErrMemory("creating buffer");
return(NULL);
}
} else
return(ret);
}
/**
* xmlBufferCreateStatic:
* @mem: the memory area
* @size: the size in byte
*
* routine to create an XML buffer from an immutable memory area.
* The area won't be modified nor copied, and is expected to be
* present until the end of the buffer lifetime.
*
* returns the new structure.
*/
return(NULL);
xmlTreeErrMemory("creating buffer");
return(NULL);
}
return(ret);
}
/**
* xmlBufferSetAllocationScheme:
* @buf: the buffer to tune
* @scheme: allocation scheme to use
*
* Sets the allocation scheme for this buffer
*/
void
#ifdef DEBUG_BUFFER
"xmlBufferSetAllocationScheme: buf == NULL\n");
#endif
return;
}
}
/**
* xmlBufferFree:
* @buf: the buffer to free
*
* Frees an XML buffer. It frees both the content and the structure which
* encapsulate it.
*/
void
#ifdef DEBUG_BUFFER
"xmlBufferFree: buf == NULL\n");
#endif
return;
}
}
}
/**
* xmlBufferEmpty:
* @buf: the buffer
*
* empty a buffer.
*/
void
} else {
}
}
/**
* xmlBufferShrink:
* @buf: the buffer to dump
* @len: the number of xmlChar to remove
*
* Remove the beginning of an XML buffer.
*
* Returns the number of #xmlChar removed, or -1 in case of failure.
*/
int
if (len == 0) return(0);
} else {
}
return(len);
}
/**
* xmlBufferGrow:
* @buf: the buffer
* @len: the minimum free size to allocate
*
* Grow the available space of an XML buffer.
*
* Returns the new available space or -1 in case of error
*/
int
int size;
/*
* Windows has a BIG problem on realloc timing, so we try to double
* the buffer size (if that's enough) (bug 146697)
*/
#ifdef WIN32
else
#else
#endif
xmlTreeErrMemory("growing buffer");
return(-1);
}
}
/**
* xmlBufferDump:
* @file: the file output
* @buf: the buffer to dump
*
* Dumps an XML buffer to a FILE *.
* Returns the number of #xmlChar written
*/
int
int ret;
#ifdef DEBUG_BUFFER
"xmlBufferDump: buf == NULL\n");
#endif
return(0);
}
#ifdef DEBUG_BUFFER
"xmlBufferDump: buf->content == NULL\n");
#endif
return(0);
}
return(ret);
}
/**
* xmlBufferContent:
* @buf: the buffer
*
* Function to extract the content of a buffer
*
* Returns the internal content
*/
const xmlChar *
{
if(!buf)
return NULL;
}
/**
* xmlBufferLength:
* @buf: the buffer
*
* Function to get the length of a buffer
*
* Returns the length of data in the internal content
*/
int
{
if(!buf)
return 0;
}
/**
* xmlBufferResize:
* @buf: the buffer to resize
* @size: the desired size
*
* Resize a buffer to accommodate minimum size of @size.
*
* Returns 0 in case of problems, 1 otherwise
*/
int
{
unsigned int newSize;
return(0);
/* Don't resize if we don't have to */
return 1;
/* figure out new size */
/*take care of empty case*/
xmlTreeErrMemory("growing buffer");
return 0;
}
newSize *= 2;
}
break;
case XML_BUFFER_ALLOC_EXACT:
break;
default:
break;
}
} else {
/*
* if we are reallocating a buffer far from being full, it's
* better to make a new allocation and copy only the used range
* and free the old one.
*/
}
}
xmlTreeErrMemory("growing buffer");
return 0;
}
return 1;
}
/**
* xmlBufferAdd:
* @buf: the buffer to dump
* @str: the #xmlChar string
* @len: the number of #xmlChar to add
*
* Add a string range to an XML buffer. if len == -1, the length of
* str is recomputed.
*
* Returns 0 successful, a positive error code number otherwise
* and -1 in case of internal or API error.
*/
int
unsigned int needSize;
return -1;
}
if (len < -1) {
#ifdef DEBUG_BUFFER
"xmlBufferAdd: len < 0\n");
#endif
return -1;
}
if (len == 0) return 0;
if (len < 0)
if (len < 0) return -1;
if (len == 0) return 0;
xmlTreeErrMemory("growing buffer");
return XML_ERR_NO_MEMORY;
}
}
return 0;
}
/**
* xmlBufferAddHead:
* @buf: the buffer
* @str: the #xmlChar string
* @len: the number of #xmlChar to add
*
* Add a string range to the beginning of an XML buffer.
* if len == -1, the length of @str is recomputed.
*
* Returns 0 successful, a positive error code number otherwise
* and -1 in case of internal or API error.
*/
int
unsigned int needSize;
return(-1);
#ifdef DEBUG_BUFFER
"xmlBufferAddHead: str == NULL\n");
#endif
return -1;
}
if (len < -1) {
#ifdef DEBUG_BUFFER
"xmlBufferAddHead: len < 0\n");
#endif
return -1;
}
if (len == 0) return 0;
if (len < 0)
if (len <= 0) return -1;
xmlTreeErrMemory("growing buffer");
return XML_ERR_NO_MEMORY;
}
}
return 0;
}
/**
* xmlBufferCat:
* @buf: the buffer to add to
* @str: the #xmlChar string
*
* Append a zero terminated string to an XML buffer.
*
* Returns 0 successful, a positive error code number otherwise
* and -1 in case of internal or API error.
*/
int
return(-1);
}
/**
* xmlBufferCCat:
* @buf: the buffer to dump
* @str: the C char string
*
* Append a zero terminated C string to an XML buffer.
*
* Returns 0 successful, a positive error code number otherwise
* and -1 in case of internal or API error.
*/
int
const char *cur;
return(-1);
#ifdef DEBUG_BUFFER
"xmlBufferCCat: str == NULL\n");
#endif
return -1;
}
xmlTreeErrMemory("growing buffer");
return XML_ERR_NO_MEMORY;
}
}
}
return 0;
}
/**
* xmlBufferWriteCHAR:
* @buf: the XML buffer
* @string: the string to add
*
* routine which manages and grows an output buffer. This one adds
* xmlChars at the end of the buffer.
*/
void
return;
}
/**
* xmlBufferWriteChar:
* @buf: the XML buffer output
* @string: the string to add
*
* routine which manage and grows an output buffer. This one add
* C chars at the end of the array.
*/
void
return;
}
/**
* xmlBufferWriteQuotedString:
* @buf: the XML buffer output
* @string: the string to add
*
* routine which manage and grows an output buffer. This one writes
* a quoted or double quoted #xmlChar string, checking first if it holds
* quote or double-quotes internally
*/
void
return;
#ifdef DEBUG_BUFFER
"xmlBufferWriteQuotedString: string contains quote and double-quotes !\n");
#endif
while(*cur != 0){
if(*cur == '"'){
cur++;
}
else {
cur++;
}
}
}
else{
}
} else {
}
}
/**
* xmlGetDocCompressMode:
* @doc: the document
*
* get the compression ratio for a document, ZLIB based
* Returns 0 (uncompressed) to 9 (max compression)
*/
int
return(doc->compression);
}
/**
* xmlSetDocCompressMode:
* @doc: the document
* @mode: the compression ratio
*
* set the compression ratio for a document, ZLIB based
* Correct values: 0 (uncompressed) to 9 (max compression)
*/
void
}
/**
* xmlGetCompressMode:
*
* get the default compression mode used, ZLIB based.
* Returns 0 (uncompressed) to 9 (max compression)
*/
int
xmlGetCompressMode(void)
{
return (xmlCompressMode);
}
/**
* xmlSetCompressMode:
* @mode: the compression ratio
*
* set the default compression mode used, ZLIB based
* Correct values: 0 (uncompressed) to 9 (max compression)
*/
void
xmlSetCompressMode(int mode) {
if (mode < 0) xmlCompressMode = 0;
else xmlCompressMode = mode;
}
#define XML_TREE_NSMAP_PARENT -1
#define XML_TREE_NSMAP_XML -2
#define XML_TREE_NSMAP_DOC -3
#define XML_TREE_NSMAP_CUSTOM -4
typedef struct xmlNsMapItem *xmlNsMapItemPtr;
struct xmlNsMapItem {
int shadowDepth; /* Shadowed at this depth */
/*
* depth:
* >= 0 == @node's ns-decls
* -1 == @parent's ns-decls
* -2 == the doc->oldNs XML ns-decl
* -3 == the doc->oldNs storage ns-decls
* -4 == ns-decls provided via custom ns-handling
*/
int depth;
};
typedef struct xmlNsMap *xmlNsMapPtr;
struct xmlNsMap {
};
#define XML_NSMAP_POP(m, i) \
i = (m)->last; \
else \
(m)->pool = i;
/*
* xmlDOMWrapNsMapFree:
* @map: the ns-map
*
* Frees the ns-map
*/
static void
{
return;
}
}
}
/*
* xmlDOMWrapNsMapAddItem:
* @map: the ns-map
* @oldNs: the old ns-struct
* @newNs: the new ns-struct
* @depth: depth and ns-kind information
*
* Adds an ns-mapping item.
*/
static xmlNsMapItemPtr
{
return(NULL);
return(NULL);
/*
* Create the ns-map.
*/
xmlTreeErrMemory("allocating namespace map");
return (NULL);
}
}
/*
* Reuse an item from the pool.
*/
} else {
/*
* Create a new item.
*/
xmlTreeErrMemory("allocating namespace map item");
return (NULL);
}
}
/*
* First ever.
*/
} else if (position == -1) {
/*
* Append.
*/
} else if (position == 0) {
/*
* Set on first position.
*/
} else
return(NULL);
return (ret);
}
/*
* xmlDOMWrapStoreNs:
* @doc: the doc
* @nsName: the namespace name
* @prefix: the prefix
*
* Creates or reuses an xmlNs struct on doc->oldNs with
* the given prefix and namespace name.
*
* Returns the aquired ns struct or NULL in case of an API
* or internal error.
*/
static xmlNsPtr
{
return (NULL);
return (NULL);
/* Reuse. */
return (ns);
}
break;
}
}
/* Create. */
}
/*
* xmlDOMWrapNewCtxt:
*
* Allocates and initializes a new DOM-wrapper context.
*
* Returns the xmlDOMWrapCtxtPtr or NULL in case of an internal errror.
*/
xmlDOMWrapNewCtxt(void)
{
xmlTreeErrMemory("allocating DOM-wrapper context");
return (NULL);
}
return (ret);
}
/*
* xmlDOMWrapFreeCtxt:
* @ctxt: the DOM-wrapper context
*
* Frees the DOM-wrapper context.
*/
void
{
return;
/*
* TODO: Store the namespace map in the context.
*/
}
/*
* xmlTreeLookupNsListByPrefix:
* @nsList: a list of ns-structs
* @prefix: the searched prefix
*
* Searches for a ns-decl with the given prefix in @nsList.
*
* Returns the ns-decl if found, NULL if not found and on
* API errors.
*/
static xmlNsPtr
{
return (NULL);
{
do {
return (ns);
}
}
return (NULL);
}
/*
*
* xmlDOMWrapNSNormGatherInScopeNs:
* @map: the namespace map
* @node: the node to start with
*
* Puts in-scope namespaces into the ns-map.
*
* Returns 0 on success, -1 on API or internal errors.
*/
static int
{
int shadowed;
return (-1);
/*
* Get in-scope ns-decls of @parent.
*/
do {
shadowed = 0;
if (XML_NSMAP_NOTEMPTY(*map)) {
/*
* Skip shadowed prefixes.
*/
shadowed = 1;
break;
}
}
}
/*
* Insert mapping.
*/
return (-1);
if (shadowed)
mi->shadowDepth = 0;
}
}
}
return (0);
}
/*
* XML_TREE_ADOPT_STR: If we have a dest-dict, put @str in the dict;
* otherwise copy it, when it was in the source-dict.
*/
#define XML_TREE_ADOPT_STR(str) \
} \
}
/*
* XML_TREE_ADOPT_STR_2: If @str was in the source-dict, then
* put it in dest-dict or copy it.
*/
#define XML_TREE_ADOPT_STR_2(str) \
else \
}
/*
* xmlDOMWrapNSNormAddNsMapItem2:
*
* For internal use. Adds a ns-decl mapping.
*
* Returns 0 on success, -1 on internal errors.
*/
static int
{
xmlTreeErrMemory("alloc ns map item");
return(-1);
}
*size = 3;
*number = 0;
*size *= 2;
xmlTreeErrMemory("realloc ns map item");
return(-1);
}
}
(*number)++;
return (0);
}
/*
* xmlDOMWrapRemoveNode:
* @ctxt: a DOM wrapper context
* @doc: the doc
* @node: the node to be removed.
* @options: set of options, unused at the moment
*
* Unlinks the given node from its owner.
* This will substitute ns-references to node->nsDef for
* ns-references to doc->oldNs, thus ensuring the removed
* branch to be autark wrt ns-references.
*
* NOTE: This function was not intensively tested.
*
* Returns 0 on success, 1 if the node is not supported,
* -1 on API and internal errors.
*/
int
{
return (-1);
/* TODO: 0 or -1 ? */
return (0);
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_ENTITY_REF_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
return (0);
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
break;
default:
return (1);
}
/*
* Save out-of-scope ns-references in doc->oldNs.
*/
do {
case XML_ELEMENT_NODE:
do {
goto internal_error;
}
/* No break on purpose. */
case XML_ATTRIBUTE_NODE:
/*
* Find a mapping.
*/
for (i = 0, j = 0; i < nbList; i++, j += 2) {
goto next_node;
}
}
}
/*
* User defined.
*/
} else {
/*
* Add to doc's oldNs.
*/
goto internal_error;
}
/*
* Add mapping.
*/
goto internal_error;
}
}
continue;
}
break;
default:
goto next_sibling;
}
continue;
}
break;
else {
goto next_sibling;
}
return (0);
return (-1);
}
/*
* xmlSearchNsByNamespaceStrict:
* @doc: the document
* @node: the start node
* @nsName: the searched namespace name
* @retNs: the resulting ns-decl
* @prefixed: if the found ns-decl must have a prefix (for attributes)
*
* Dynamically searches for a ns-declaration which matches
* the given @nsName in the ancestor-or-self axis of @node.
*
* Returns 1 if a ns-decl was found, 0 if not and -1 on API
* and internal errors.
*/
static int
{
return (-1);
return (-1);
return (1);
}
do {
continue;
/*
* Check the last level of ns-decls for a
* shadowing prefix.
*/
do {
/*
* Shadowed.
*/
break;
}
continue;
}
/*
* Ns-name comparison.
*/
/*
* At this point the prefix can only be shadowed,
* if we are the the (at least) 3rd level of
* ns-decls.
*/
if (out) {
int ret;
if (ret < 0)
return (-1);
/*
* TODO: Should we try to find a matching ns-name
* only once? This here keeps on searching.
* I think we should try further since, there might
* be an other matching ns-decl with an unshadowed
* prefix.
*/
if (! ret)
continue;
}
return (1);
}
}
}
return (0);
return (0);
}
/*
* xmlSearchNsByPrefixStrict:
* @doc: the document
* @node: the start node
* @prefix: the searched namespace prefix
* @retNs: the resulting ns-decl
*
* Dynamically searches for a ns-declaration which matches
* the given @nsName in the ancestor-or-self axis of @node.
*
* Returns 1 if a ns-decl was found, 0 if not and -1 on API
* and internal errors.
*/
static int
{
return (-1);
if (retNs)
if (IS_STR_XML(prefix)) {
if (retNs) {
return (-1);
}
return (1);
}
do {
do {
{
/*
* Disabled namespaces, e.g. xmlns:abc="".
*/
return(0);
if (retNs)
return (1);
}
}
return (0);
return (0);
}
/*
* xmlDOMWrapNSNormDeclareNsForced:
* @doc: the doc
* @elem: the element-node to declare on
* @nsName: the namespace-name of the ns-decl
* @prefix: the preferred prefix of the ns-decl
* @checkShadow: ensure that the new ns-decl doesn't shadow ancestor ns-decls
*
* Declares a new namespace on @elem. It tries to use the
* given @prefix; if a ns-decl with the given prefix is already existent
* on @elem, it will generate an other prefix.
*
* Returns 1 if a ns-decl was found, 0 if not and -1 on API
* and internal errors.
*/
static xmlNsPtr
int checkShadow)
{
char buf[50];
int counter = 0;
/*
* Create a ns-decl on @anchor.
*/
while (1) {
/*
* Lookup whether the prefix is unused in elem's ns-decls.
*/
goto ns_next_prefix;
/*
* Does it shadow ancestor ns-decls?
*/
goto ns_next_prefix;
}
return (NULL);
else {
}
return (ret);
counter++;
if (counter > 1000)
return (NULL);
"ns_%d", counter);
} else
}
}
/*
* xmlDOMWrapNSNormAquireNormalizedNs:
* @doc: the doc
* @elem: the element-node to declare namespaces on
* @ns: the ns-struct to use for the search
* @nsMap: the ns-map
* @depth: the current tree depth
* @ancestorsOnly: search in ancestor ns-decls only
* @prefixed: if the searched ns-decl must have a prefix (for attributes)
*
* Searches for a matching ns-name in the ns-decls of @nsMap, if not
* found it will either declare it on @elem, or store it in doc->oldNs.
* If a new ns-decl needs to be declared on @elem, it tries to use the
* @ns->prefix for it, if this prefix is already in use on @elem, it will
* change the prefix or the new ns-decl.
*
*/
static int
int depth,
int ancestorsOnly,
int prefixed)
{
return (-1);
/*
* Handle XML namespace.
*/
/*
* Insert XML namespace mapping.
*/
return (-1);
return (0);
}
/*
* If the search should be done in ancestors only and no
* @elem (the first ancestor) was specified, then skip the search.
*/
if ((XML_NSMAP_NOTEMPTY(*nsMap)) &&
{
/*
* Try to find an equal ns-name in in-scope ns-decls.
*/
/*
* ancestorsOnly: This should be turned on to gain speed,
* if one knows that the branch itself was already
* ns-wellformed and no stale references existed.
* I.e. it searches in the ancestor axis only.
*/
/* Skip shadowed prefixes. */
/* Skip xmlns="" or xmlns:foo="". */
/* Ensure a prefix if wanted. */
/* Equal ns name */
/* Set the mapping. */
return (0);
}
}
}
/*
* No luck, the namespace is out of scope or shadowed.
*/
/*
* Store ns-decls in "oldNs" of the document-node.
*/
return (-1);
/*
* Insert mapping.
*/
return (-1);
}
} else {
return (-1);
/*
* Does it shadow ancestor ns-decls?
*/
/*
* Shadows.
*/
break;
}
}
}
return (-1);
}
}
return (0);
}
typedef enum {
XML_DOM_RECONNS_REMOVEREDUND = 1<<0
/*
* xmlDOMWrapReconcileNamespaces:
* @ctxt: DOM wrapper context, unused at the moment
* @elem: the element-node
* @options: option flags
*
* Ensures that ns-references point to ns-decls hold on element-nodes.
* Ensures that the tree is namespace wellformed by creating additional
* ns-decls where needed. Note that, since prefixes of already existent
* ns-decls can be shadowed by this process, it could break QNames in
* attribute values or element content.
*
* NOTE: This function was not intensively tested.
*
*/
int
int options)
{
/* @ancestorsOnly should be set by an option flag. */
int ancestorsOnly = 0;
int optRemoveRedundantNS =
return (-1);
do {
case XML_ELEMENT_NODE:
adoptns = 1;
depth++;
/*
* Namespace declarations.
*/
if (! parnsdone) {
/*
* Gather ancestor in-scope ns-decls.
*/
goto internal_error;
}
parnsdone = 1;
}
/*
* Lookup the ns ancestor-axis for equal ns-decls in scope.
*/
{
/*
* A redundant ns-decl was found.
* Add it to the list of redundant ns-decls.
*/
goto internal_error;
/*
* Remove the ns-decl from the element-node.
*/
if (prevns)
else
goto next_ns_decl;
}
}
}
/*
* Skip ns-references handling if the referenced
* ns-decl is declared on the same element.
*/
adoptns = 0;
/*
* Does it shadow any ns-decl?
*/
if (XML_NSMAP_NOTEMPTY(nsMap)) {
}
}
}
/*
* Push mapping.
*/
goto internal_error;
}
}
if (! adoptns)
goto ns_end;
/* No break on purpose. */
case XML_ATTRIBUTE_NODE:
/* No ns, no fun. */
goto ns_end;
if (! parnsdone) {
goto internal_error;
}
parnsdone = 1;
}
/*
* Adjust the reference if this was a redundant ns-decl.
*/
if (listRedund) {
for (i = 0, j = 0; i < nbRedund; i++, j += 2) {
break;
}
}
}
/*
* Adopt ns-references.
*/
if (XML_NSMAP_NOTEMPTY(nsMap)) {
/*
* Search for a mapping.
*/
goto ns_end;
}
}
}
/*
* Aquire a normalized ns-decl and add it to the map.
*/
goto internal_error;
/*
* Process attributes.
*/
continue;
}
break;
default:
goto next_sibling;
}
/*
* Process content of element-nodes only.
*/
continue;
}
break;
if (XML_NSMAP_NOTEMPTY(nsMap)) {
/*
* Pop mappings.
*/
{
}
/*
* Unshadow.
*/
}
}
depth--;
}
else {
goto into_content;
}
goto next_sibling;
}
ret = 0;
goto exit;
ret = -1;
exit:
if (listRedund) {
for (i = 0, j = 0; i < nbRedund; i++, j += 2) {
xmlFreeNs(listRedund[j]);
}
}
return (ret);
}
/*
* xmlDOMWrapAdoptBranch:
* @ctxt: the optional context for custom processing
* @sourceDoc: the optional sourceDoc
* @node: the element-node to start with
* @destDoc: the destination doc for adoption
* @destParent: the optional new parent of @node in @destDoc
* @options: option flags
*
* Ensures that ns-references point to @destDoc: either to
* elements->nsDef entries if @destParent is given, or to
* @destDoc->oldNs otherwise.
* If @destParent is given, it ensures that the tree is namespace
* wellformed by creating additional ns-decls where needed.
* Note that, since prefixes of already existent ns-decls can be
* shadowed by this process, it could break QNames in attribute
* values or element content.
*
* NOTE: This function was not intensively tested.
*
*/
static int
int options ATTRIBUTE_UNUSED)
{
int ret = 0;
/* gather @parent's ns-decls. */
int parnsdone;
/* @ancestorsOnly should be set per option. */
int ancestorsOnly = 0;
/*
* Optimize string adoption for equal or none dicts.
*/
adoptStr = 0;
else
adoptStr = 1;
/*
* Get the ns-map from the context if available.
*/
if (ctxt)
/*
* Disable search for ns-decls in the parent-axis of the
* desination element, if:
* 1) there's no destination parent
* 2) custom ns-reference handling is used
*/
if ((destParent == NULL) ||
{
parnsdone = 1;
} else
parnsdone = 0;
/*
* Paranoid source-doc sanity check.
*/
/*
* We'll assume XIncluded nodes if the doc differs.
* TODO: Do we need to reconciliate XIncluded nodes?
* This here skips XIncluded nodes and tries to handle
* broken sequences.
*/
goto leave_node;
do {
break;
goto leave_node;
}
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
/*
* TODO
*/
return (-1);
case XML_ELEMENT_NODE:
depth++;
/*
* Namespace declarations.
* - ns->href and ns->prefix are never in the dict, so
* we need not move the values over to the destination dict.
* - Note that for custom handling of ns-references,
* the ns-decls need not be stored in the ns-map,
* since they won't be referenced by node->ns.
*/
{
if (! parnsdone) {
/*
* Gather @parent's in-scope ns-decls.
*/
destParent) == -1)
goto internal_error;
parnsdone = 1;
}
/*
* NOTE: ns->prefix and ns->href are never in the dict.
* XML_TREE_ADOPT_STR(ns->prefix)
* XML_TREE_ADOPT_STR(ns->href)
*/
/*
* Does it shadow any ns-decl?
*/
if (XML_NSMAP_NOTEMPTY(nsMap)) {
}
}
}
/*
* Push mapping.
*/
goto internal_error;
}
}
/* No break on purpose. */
case XML_ATTRIBUTE_NODE:
/* No namespace, no fun. */
goto ns_end;
if (! parnsdone) {
destParent) == -1)
goto internal_error;
parnsdone = 1;
}
/*
* Adopt ns-references.
*/
if (XML_NSMAP_NOTEMPTY(nsMap)) {
/*
* Search for a mapping.
*/
goto ns_end;
}
}
}
/*
* No matching namespace in scope. We need a new one.
*/
/*
* User-defined behaviour.
*/
/*
* Insert mapping if ns is available; it's the users fault
* if not.
*/
goto internal_error;
} else {
/*
* Aquire a normalized ns-decl and add it to the map.
*/
/* ns-decls on curElem or on destDoc->oldNs */
/* ns-decls must be prefixed for attributes. */
goto internal_error;
}
/*
* Further node properties.
* TODO: Is this all?
*/
/*
* Walk attributes.
*/
/*
* Process first attribute node.
*/
continue;
}
} else {
/*
* Attributes.
*/
{
}
}
break;
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
/*
* This puts the content in the dest dict, only if
* it was previously in the source dict.
*/
goto leave_node;
case XML_ENTITY_REF_NODE:
/*
* Remove reference to the entitity-node.
*/
/*
* Assign new entity-node if available.
*/
}
}
goto leave_node;
case XML_PI_NODE:
break;
case XML_COMMENT_NODE:
break;
default:
goto internal_error;
}
/*
* Walk the tree.
*/
continue;
}
break;
{
/*
* TODO: Do we expect nsDefs on XML_XINCLUDE_START?
*/
if (XML_NSMAP_NOTEMPTY(nsMap)) {
/*
* Pop mappings.
*/
{
}
/*
* Unshadow.
*/
}
}
depth--;
}
{
} else {
goto leave_node;
}
}
goto exit;
ret = -1;
exit:
/*
* Cleanup.
*/
/*
* Just cleanup the map but don't free.
*/
}
} else
}
return(ret);
}
/*
* xmlDOMWrapCloneNode:
* @ctxt: the optional context for custom processing
* @sourceDoc: the optional sourceDoc
* @node: the node to start with
* @resNode: the clone of the given @node
* @destDoc: the destination doc
* @destParent: the optional new parent of @node in @destDoc
* @deep: descend into child if set
* @options: option flags
*
* References of out-of scope ns-decls are remapped to point to @destDoc:
* 1) If @destParent is given, then nsDef entries on element-nodes are used
* 2) If *no* @destParent is given, then @destDoc->oldNs entries are used.
* This is the case when you don't know already where the cloned branch
* will be added to.
*
* If @destParent is given, it ensures that the tree is namespace
* wellformed by creating additional ns-decls where needed.
* Note that, since prefixes of already existent ns-decls can be
* shadowed by this process, it could break QNames in attribute
* values or element content.
* TODO:
* 1) What to do with XInclude? Currently this returns an error for XInclude.
*
* Returns 0 if the operation succeeded,
* 1 if a node of unsupported (or not yet supported) type was given,
*/
int
int deep,
int options ATTRIBUTE_UNUSED)
{
int ret = 0;
int depth = -1;
/* int adoptStr = 1; */
/* gather @parent's ns-decls. */
int parnsdone = 0;
/*
* @ancestorsOnly:
* TODO: @ancestorsOnly should be set per option.
*
*/
int ancestorsOnly = 0;
return(-1);
/*
* TODO: Initially we support only element-nodes.
*/
return(1);
/*
* Check node->doc sanity.
*/
/*
* Might be an XIncluded node.
*/
return (-1);
}
return (-1);
/*
* Reuse the namespace map of the context.
*/
if (ctxt)
/*
* We'll assume XIncluded nodes if the doc differs.
* TODO: Do we need to reconciliate XIncluded nodes?
* TODO: This here returns -1 in this case.
*/
goto internal_error;
}
/*
* Create a new node.
*/
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
/*
* TODO: What to do with XInclude?
*/
goto internal_error;
break;
case XML_ELEMENT_NODE:
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_COMMENT_NODE:
case XML_PI_NODE:
case XML_DOCUMENT_FRAG_NODE:
case XML_ENTITY_REF_NODE:
case XML_ENTITY_NODE:
/*
* Nodes of xmlNode structure.
*/
xmlTreeErrMemory("xmlDOMWrapCloneNode(): allocating a node");
goto internal_error;
}
/*
* Set hierachical links.
*/
if (resultClone != NULL) {
if (prevClone) {
} else
} else
resultClone = clone;
break;
case XML_ATTRIBUTE_NODE:
/*
* Attributes (xmlAttr).
*/
xmlTreeErrMemory("xmlDOMWrapCloneNode(): allocating an attr-node");
goto internal_error;
}
/*
* Set hierachical links.
* TODO: Change this to add to the end of attributes.
*/
if (resultClone != NULL) {
if (prevClone) {
} else
} else
resultClone = clone;
break;
default:
/*
* TODO QUESTION: Any other nodes expected?
*/
goto internal_error;
}
/*
* Clone the name of the node if any.
*/
/*
* NOTE: Although xmlStringTextNoenc is never assigned to a node
* in tree.c, it might be set in Libxslt via
* "xsl:disable-output-escaping".
*/
}
case XML_XINCLUDE_START:
case XML_XINCLUDE_END:
/*
* TODO
*/
return (-1);
case XML_ELEMENT_NODE:
depth++;
/*
* Namespace declarations.
*/
if (! parnsdone) {
/*
* Gather @parent's in-scope ns-decls.
*/
destParent) == -1)
goto internal_error;
}
parnsdone = 1;
}
/*
* Clone namespace declarations.
*/
/*
* Create a new xmlNs.
*/
xmlTreeErrMemory("xmlDOMWrapCloneNode(): "
"allocating namespace");
return(-1);
}
/*
* Note that for custom handling of ns-references,
* the ns-decls need not be stored in the ns-map,
* since they won't be referenced by node->ns.
*/
{
/*
* Does it shadow any ns-decl?
*/
if (XML_NSMAP_NOTEMPTY(nsMap)) {
/*
* Mark as shadowed at the current
* depth.
*/
}
}
}
/*
* Push mapping.
*/
goto internal_error;
}
}
}
/* cur->ns will be processed further down. */
break;
case XML_ATTRIBUTE_NODE:
/* IDs will be processed further down. */
/* cur->ns will be processed further down. */
break;
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
/*
* Note that this will also cover the values of attributes.
*/
goto leave_node;
case XML_ENTITY_NODE:
/* TODO: What to do here? */
goto leave_node;
case XML_ENTITY_REF_NODE:
/*
* Different doc: Assign new entity-node if available.
*/
}
}
} else {
/*
* Same doc: Use the current node's entity declaration
* and value.
*/
}
goto leave_node;
case XML_PI_NODE:
goto leave_node;
case XML_COMMENT_NODE:
goto leave_node;
default:
goto internal_error;
}
goto end_ns_reference;
/* handle_ns_reference: */
/*
** The following will take care of references to ns-decls ********
** and is intended only for element- and attribute-nodes.
**
*/
if (! parnsdone) {
goto internal_error;
}
parnsdone = 1;
}
/*
* Adopt ns-references.
*/
if (XML_NSMAP_NOTEMPTY(nsMap)) {
/*
* Search for a mapping.
*/
/*
* This is the nice case: a mapping was found.
*/
goto end_ns_reference;
}
}
}
/*
* No matching namespace in scope. We need a new one.
*/
/*
* User-defined behaviour.
*/
/*
* Add user's mapping.
*/
goto internal_error;
} else {
/*
* Aquire a normalized ns-decl and add it to the map.
*/
/* ns-decls on curElem or on destDoc->oldNs */
/* if we need to search only in the ancestor-axis */
/* ns-decls must be prefixed for attributes. */
goto internal_error;
}
/*
* Some post-processing.
*
* Handle ID attributes.
*/
{
/* TODO: error message. */
goto internal_error;
}
}
}
}
/*
**
** The following will traverse the tree **************************
**
*
* Walk the element's attributes before descending into child-nodes.
*/
parentClone = clone;
continue;
}
/*
* Descend into child-nodes.
*/
parentClone = clone;
continue;
}
}
/*
* At this point we are done with the node, its content
* and an element-nodes's attribute-nodes.
*/
break;
/*
* TODO: Do we expect nsDefs on XML_XINCLUDE_START?
*/
if (XML_NSMAP_NOTEMPTY(nsMap)) {
/*
* Pop mappings.
*/
{
}
/*
* Unshadow.
*/
}
}
depth--;
}
/*
* Set clone->last.
*/
/*
* Process parent --> next;
*/
goto leave_node;
} else {
/* This is for attributes only. */
/*
* Process parent-element --> children.
*/
goto into_content;
}
}
goto exit;
ret = -1;
exit:
/*
* Cleanup.
*/
/*
* Just cleanup the map but don't free.
*/
}
} else
}
/*
* TODO: Should we try a cleanup of the cloned node in case of a
* fatal error?
*/
*resNode = resultClone;
return (ret);
}
/*
* xmlDOMWrapAdoptAttr:
* @ctxt: the optional context for custom processing
* @sourceDoc: the optional source document of attr
* @attr: the attribute-node to be adopted
* @destDoc: the destination doc for adoption
* @destParent: the optional new parent of @attr in @destDoc
* @options: option flags
*
* @attr is adopted by @destDoc.
* Ensures that ns-references point to @destDoc: either to
* elements->nsDef entries if @destParent is given, or to
* @destDoc->oldNs otherwise.
*
*/
static int
int options ATTRIBUTE_UNUSED)
{
int adoptStr = 1;
return (-1);
/* TODO: User defined. */
}
/* XML Namespace. */
} else if (destParent == NULL) {
/*
* Store in @destDoc->oldNs.
*/
} else {
/*
* Declare on @destParent.
*/
goto internal_error;
}
}
goto internal_error;
}
/*
* Walk content.
*/
return (0);
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
break;
case XML_ENTITY_REF_NODE:
/*
* Remove reference to the entitity-node.
*/
/*
* Assign new entity-node if available.
*/
}
}
break;
default:
break;
}
continue;
}
break;
else {
goto next_sibling;
}
}
return (0);
return (-1);
}
/*
* xmlDOMWrapAdoptNode:
* @ctxt: the optional context for custom processing
* @sourceDoc: the optional sourceDoc
* @node: the node to start with
* @destDoc: the destination doc
* @destParent: the optional new parent of @node in @destDoc
* @options: option flags
*
* References of out-of scope ns-decls are remapped to point to @destDoc:
* 1) If @destParent is given, then nsDef entries on element-nodes are used
* 2) If *no* @destParent is given, then @destDoc->oldNs entries are used
* This is the case when you have an unliked node and just want to move it
* to the context of
*
* If @destParent is given, it ensures that the tree is namespace
* wellformed by creating additional ns-decls where needed.
* Note that, since prefixes of already existent ns-decls can be
* shadowed by this process, it could break QNames in attribute
* values or element content.
* NOTE: This function was not intensively tested.
*
* Returns 0 if the operation succeeded,
* 1 if a node of unsupported type was given,
* 2 if a node of not yet supported type was given and
*/
int
int options)
{
return(-1);
/*
* Check node->doc sanity.
*/
/*
* Might be an XIncluded node.
*/
return (-1);
}
return (-1);
case XML_ELEMENT_NODE:
case XML_ATTRIBUTE_NODE:
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
case XML_ENTITY_REF_NODE:
case XML_PI_NODE:
case XML_COMMENT_NODE:
break;
case XML_DOCUMENT_FRAG_NODE:
/* TODO: Support document-fragment-nodes. */
return (2);
default:
return (1);
}
/*
* Unlink only if @node was not already added to @destParent.
*/
} else {
int adoptStr = 1;
/*
* Optimize string adoption.
*/
adoptStr = 0;
case XML_TEXT_NODE:
case XML_CDATA_SECTION_NODE:
break;
case XML_ENTITY_REF_NODE:
/*
* Remove reference to the entitity-node.
*/
/*
* Assign new entity-node if available.
*/
}
}
break;
case XML_PI_NODE: {
break;
}
default:
break;
}
}
return (0);
}
#define bottom_tree
#include "elfgcchack.h"