mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2024-10-26 20:25:14 +03:00
handle and explain a very tricky problem when modifying the tree based on
* doc/examples/xpath2.c doc/examples/xpath2.res: handle and explain a very tricky problem when modifying the tree based on an XPath result query. Daniel
This commit is contained in:
parent
6092962595
commit
3d354a798e
@ -1,3 +1,9 @@
|
||||
Sun Mar 28 14:17:10 CEST 2004 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* doc/examples/xpath2.c doc/examples/xpath2.res: handle and explain
|
||||
a very tricky problem when modifying the tree based on an XPath
|
||||
result query.
|
||||
|
||||
Sat Mar 27 09:56:14 PST 2004 William Brack <wbrack@mmm.com.hk>
|
||||
|
||||
* relaxng.c: fixed problem with IS_COMPILABLE flag
|
||||
|
@ -120,7 +120,7 @@ tests: $(noinst_PROGRAMS)
|
||||
@(grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0)
|
||||
@($(CHECKER) ./io2 > io2.tmp ; diff io2.tmp io2.res ; rm -f io2.tmp)
|
||||
@(grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0)
|
||||
@($(CHECKER) ./xpath2 test3.xml '//child2' child2 > xpath2.tmp ; diff xpath2.tmp xpath2.res ; rm xpath2.tmp)
|
||||
@($(CHECKER) ./xpath2 test3.xml '//discarded' discarded > xpath2.tmp ; diff xpath2.tmp xpath2.res ; rm xpath2.tmp)
|
||||
@(grep "MORY ALLO" .memdump | grep -v "MEMORY ALLOCATED : 0" ; exit 0)
|
||||
|
||||
|
||||
|
@ -340,7 +340,7 @@
|
||||
<synopsis>Load a document, locate subelements with XPath, modify said elements and save the resulting document.</synopsis>
|
||||
<purpose>Shows how to make a full round-trip from a load/edit/save</purpose>
|
||||
<usage>xpath2 <xml-file> <xpath-expr> <new-value></usage>
|
||||
<test>xpath2 test3.xml '//child2' child2 > xpath2.tmp ; diff xpath2.tmp xpath2.res ; rm xpath2.tmp</test>
|
||||
<test>xpath2 test3.xml '//discarded' discarded > xpath2.tmp ; diff xpath2.tmp xpath2.res ; rm xpath2.tmp</test>
|
||||
<author>Aleksey Sanin and Daniel Veillard</author>
|
||||
<copy>see Copyright for the status of this software. </copy>
|
||||
<section>XPath</section>
|
||||
@ -360,6 +360,7 @@
|
||||
<typedef line='86' file='xpath' name='xmlXPathContextPtr'/>
|
||||
<function line='123' file='xpath' name='xmlXPathFreeContext'/>
|
||||
<function line='40' file='parser' name='xmlInitParser'/>
|
||||
<enum line='179' file='tree' name='XML_NAMESPACE_DECL'/>
|
||||
<function line='94' file='parser' name='xmlParseFile'/>
|
||||
</uses>
|
||||
</example>
|
||||
@ -381,6 +382,7 @@
|
||||
</symbol>
|
||||
<symbol name='XML_NAMESPACE_DECL'>
|
||||
<ref filename='xpath1.c'/>
|
||||
<ref filename='xpath2.c'/>
|
||||
</symbol>
|
||||
<symbol name='XML_PARSE_DTDATTR'>
|
||||
<ref filename='reader2.c'/>
|
||||
|
@ -4,7 +4,7 @@
|
||||
* said elements and save the resulting document.
|
||||
* purpose: Shows how to make a full round-trip from a load/edit/save
|
||||
* usage: xpath2 <xml-file> <xpath-expr> <new-value>
|
||||
* test: xpath2 test3.xml '//child2' child2 > xpath2.tmp ; diff xpath2.tmp xpath2.res ; rm xpath2.tmp
|
||||
* test: xpath2 test3.xml '//discarded' discarded > xpath2.tmp ; diff xpath2.tmp xpath2.res ; rm xpath2.tmp
|
||||
* author: Aleksey Sanin and Daniel Veillard
|
||||
* copy: see Copyright for the status of this software.
|
||||
*/
|
||||
@ -159,6 +159,25 @@ update_xpath_nodes(xmlNodeSetPtr nodes, const xmlChar* value) {
|
||||
assert(nodes->nodeTab[i]);
|
||||
|
||||
xmlNodeSetContent(nodes->nodeTab[i], value);
|
||||
/*
|
||||
* All the elements returned by an XPath query are pointers to
|
||||
* elements from the tree *except* namespace nodes where the XPath
|
||||
* semantic is different from the implementation in libxml2 tree.
|
||||
* As a result when a returned node set is freed when
|
||||
* xmlXPathFreeObject() is called, that routine must check the
|
||||
* element type. But node from the returned set may have been removed
|
||||
* by xmlNodeSetContent() resulting in access to freed data.
|
||||
* This can be exercised by running
|
||||
* valgrind xpath2 test3.xml '//discarded' discarded
|
||||
* There is 2 ways around it:
|
||||
* - make a copy of the pointers to the nodes from the result set
|
||||
* then call xmlXPathFreeObject() and then modify the nodes
|
||||
* or
|
||||
* - remove the reference to the modified nodes from the node set
|
||||
* as they are processed, if they are not namespace nodes.
|
||||
*/
|
||||
if (nodes->nodeTab[i]->type != XML_NAMESPACE_DECL)
|
||||
nodes->nodeTab[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,38 +1,30 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<parent>
|
||||
<discarded>
|
||||
<discarded/>
|
||||
</discarded>
|
||||
<discarded>discarded</discarded>
|
||||
<preserved/>
|
||||
This text node must be discarded
|
||||
<discarded>
|
||||
<discarded/>
|
||||
</discarded>
|
||||
<discarded>discarded</discarded>
|
||||
<preserved>
|
||||
content1
|
||||
<child1/>
|
||||
<child2>child2</child2>
|
||||
<child2>content2</child2>
|
||||
<preserved>too</preserved>
|
||||
<child2>child2</child2>
|
||||
<child2>content3</child2>
|
||||
<preserved/>
|
||||
<child2>child2</child2>
|
||||
<child2>content4</child2>
|
||||
<preserved/>
|
||||
<child2>child2</child2>
|
||||
<child2>content5</child2>
|
||||
content6
|
||||
</preserved>
|
||||
This text node must be discarded
|
||||
<discarded>
|
||||
<discarded/>
|
||||
</discarded>
|
||||
<discarded>discarded</discarded>
|
||||
This text node must be discarded
|
||||
<preserved/>
|
||||
This text node must be discarded
|
||||
<preserved/>
|
||||
This text node must be discarded
|
||||
<discarded>
|
||||
<discarded/>
|
||||
</discarded>
|
||||
<discarded>discarded</discarded>
|
||||
This text node must be discarded
|
||||
</parent>
|
||||
</doc>
|
||||
|
Loading…
Reference in New Issue
Block a user