Commit 3d354a79 authored by Daniel Veillard's avatar Daniel Veillard
Browse files

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
parent 60929625
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 &lt;xml-file&gt; &lt;xpath-expr&gt; &lt;new-value&gt;</usage>
<test>xpath2 test3.xml &apos;//child2&apos; child2 &gt; xpath2.tmp ; diff xpath2.tmp xpath2.res ; rm xpath2.tmp</test>
<test>xpath2 test3.xml &apos;//discarded&apos; discarded &gt; 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;
}
}
......
<?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>
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment