2013-05-15 40 views
5

我想合併2個具有相同結構的XML文件來創建一個。例如;如何使用Xinclude與Xinclude引用元素

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> 

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> 

要創建

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> 

即一個包含所有元素的XML文件。

我在StackOverflow上找到了一個有用的問題,並提出了這個問題;

的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> 

這一點我做這個運行(我需要使用xmllint爲理由介入進入)

xmllint -xinclude的merge.xml

但這不起作用,它抱怨各種thiongs,這似乎與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> 

如果我省略了XPointer的屬性在的merge.xml然後我得到一些合理的輸出,但它已經做了超過包括我當然要的元素。

有人可以提供一些建議,因爲我在做xpointer錯誤嗎?

謝謝你的支持。

+0

如果我刪除名稱空間,上述工作,所以這只是XPointer的問題,我如何處理名稱空間 – Nerdio

+0

'element()'方案不支持限定名稱(請參見https:// www.w3.org/TR/xptr-element/)。用'element()'指定的名稱必須是一個NCName,並且指的是用該名稱的xs:ID標識的_single_元素。這顯然不是你想要的。 –

回答

3

我已經涉足這個多一點,並找到了很多的網絡上的例子暗示什麼,我做的是correct.This現在是一個工作版本

<?xml version="1.0"?> 

<Root xmlns:xi="http://www.w3.org/2003/XInclude" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:ns="http://testurl.com/now"> 

    <xi:include href="Test1.xml" xpointer="xmlns(ns=http://testurl.com/now)xpointer(/ns:Root/ns:element1)" parse="xml" /> 
    <xi:include href="Test2.xml" xpointer="xpointer(//Root/element1)" parse="xml" /> 

</Root> 

本例中使用具有名稱空間的Test1.xml版本,以及不具有Test2.xml的版本。

現在的輸出看起來是這樣的....

<?xml version="1.0"?> 
<Root xmlns:xi="http://www.w3.org/2003/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns="http://testurl.com/now"> 

    <ns:element1 xmlns:ns="http://testurl.com/now" 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 xmlns:ns="http://testurl.com/now" id="003"> 
     <ns:element2 id="007.0" order="1"> 
      <ns:element3 id="007.1.1"/> 
     </ns:element2> 
    </ns:element1><ns:element1 xmlns:ns="http://testurl.com/now" id="002"> 
     <ns:element2 id="002.1" order="3"> 
      <ns:element3 id="002.1.1"/> 
     </ns:element2> 
     <ns:element2 id="002.2" order="4"> 
      <ns:element3 id="002.1.2"/> 
     </ns:element2> 
    </ns:element1> 
    <element1 id="999"> 
     <element2 id="999.1" order="1"> 
      <element3 id="999.1.1"/> 
     </element2> 
    </element1> 

</Root> 

當然,這是可以接受的,這將是很好,如果行的打開和關閉的部件1之間爆發仍然存在

+0

換行符不是元素的一部分,因此不能在引用元素時出現。嘗試在xmllint命令行中添加'--pretty 1':'xmllint --pretty 1 -xinclude Merge.xml'。這仍然不會重現原來的間距,但看起來更好一點。 –

0

這與名稱空間一起使用:

<?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" xpointer="xpointer(*/*)" /> 
    <xi:include href="Test2.xml" xpointer="xpointer(*/*)" /> 

</ns:Root> 

另外parse="xml"是默認值。你不需要指定它。