I want to merge 2 XML files with the same structure to make one. For example;
Test1.xml
<?xml version="1.0" encoding="UTF-8"?>
<ns:Root
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns="urn:TestNamespace"
xsi:schemaLocation="urn:Test.Namespace Test1.xsd"
>
<ns:element1 id="001">
<ns:element2 id="001.1" order="1">
<ns:element3 id="001.1.1" />
</ns:element2>
<ns:element2 id="001.2" order="2">
<ns:element3 id="001.1.2" />
</ns:element2>
</ns:element1>
</ns:Root>
and Test2.xml
<?xml version="1.0" encoding="UTF-8"?>
<ns:Root
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns="urn:TestNamespace"
xsi:schemaLocation="urn:Test.Namespace Test1.xsd"
>
<ns:element1 id="999">
<ns:element2 id="999.1" order="1">
<ns:element3 id="999.1.1" />
</ns:element2>
</ns:element1>
</ns:Root>
To create
TestOutput.xml
<?xml version="1.0" encoding="UTF-8"?>
<ns:Root
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns="urn:TestNamespace"
xsi:schemaLocation="urn:Test.Namespace Test1.xsd"
>
<ns:element1 id="001">
<ns:element2 id="001.1" order="1">
<ns:element3 id="001.1.1" />
</ns:element2>
<ns:element2 id="001.2" order="2">
<ns:element3 id="001.1.2" />
</ns:element2>
</ns:element1>
<ns:element1 id="999">
<ns:element2 id="999.1" order="1">
<ns:element3 id="999.1.1" />
</ns:element2>
</ns:element1>
</ns:Root>
ie one XML file with all the elements from each included.
I found a useful question on StackOverflow, and came up with this;
Merge.xml
<?xml version="1.0"?>
<ns:Root xmlns:xi="http://www.w3.org/2003/XInclude"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns="urn:TestNamespace">
<xi:include href="Test1.xml" parse="xml" xpointer="element(//ns:Root/ns:element1)" />
<xi:include href="Test2.xml" parse="xml" xpointer="element(//ns:Root/ns:element1)" />
</ns:Root>
Which I run by doing this (I need to use xmllint for reasons to involved to go into)
xmllint -xinclude Merge.xml
But this does not work, it complains about various thiongs, which seem to relate to xpointer.
parser error : warning: ChildSeq not starting by /1
Merge.xml:7: element include: XInclude error : XPointer evaluation failed: #element(//ns:Root/ns:element1)
Merge.xml:7: element include: XInclude error : could not load Test1.xml, and no fallback was found
parser error : warning: ChildSeq not starting by /1
Merge.xml:9: element include: XInclude error : XPointer evaluation failed: #element(//ns:Root/ns:element1)
Merge.xml:9: element include: XInclude error : could not load Test2.xml, and no fallback was found
<?xml version="1.0"?>
<ns:Root xmlns:xi="http://www.w3.org/2003/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns="urn:TestNamespace">
<xi:include href="Test1.xml" parse="xml" xpointer="element(//ns:Root/ns:element1)"/>
<xi:include href="Test2.xml" parse="xml" xpointer="element(//ns:Root/ns:element1)"/>
</ns:Root>
If I omit the xpointer attributes in Merge.xml then I get some sensible output, but it has done more than include the elements I want of course.
Can someone offer some advice as to what I am doing wrong with xpointer please?
Thanks in antcipation.
This works with and without namespaces:
Also
parse="xml"
is default. You don't need to specify it.I have dabbled with this a bit more, and found plenty of examples on the web that suggest what I am doing is correct.This is now a working version...
This example uses a version of Test1.xml which has namespaces, and Test2.xml which does not.
The output now looks like this....
This is of course acceptable, it would be nice if the line breaks between the open and close of element1 were still there