2013-05-15 17 views
5

同じ構造を持つ2つのXMLファイルをマージして1つにしたいと思っています。例えば; Test1.xmlxpointerとXincludeを参照要素に使用する方法

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

つまり、それぞれからのすべての要素を含む1つの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> 

はMerge.xml

-xinclude

xmllintを(私がに行くことに関与する理由のためにxmllintを使用する必要があります)

しかし、これはうまくいかず、xpointerに関連しているように見えるさまざまなthiongについて不平を言います。

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> 

私はMerge.xmlにXPointerの属性を省略した場合、私はいくつかの賢明な出力を得るが、それは、私はもちろんしたい要素を含む以上行っています。

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> 

この例では、A使用しています名前空間を持つ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"がデフォルトです。あなたはそれを指定する必要はありません。

関連する問題