2013-05-15 9 views
5

Voglio unire 2 file XML con la stessa struttura per crearne uno. Per esempio;Come utilizzare xpointer con Xinclude agli elementi di riferimento

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> 

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

Per creare

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> 

cioè un file XML con tutti gli elementi di ciascuno inclusi.

Ho trovato una domanda utile su StackOverflow e ho trovato questo;

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> 

che corro in questo modo (ho bisogno di usare xmllint per motivi di coinvolgere di andare in)

xmllint -xinclude Merge.xml

Ma questo non funziona, si lamenta di vari thiongs, che sembrano riguardare 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> 

Se Tralascio gli attributi XPointer in Merge.xml tanto sono un po 'di uscita ragionevole, ma ha fatto più di includere gli elementi che voglio naturalmente.

Qualcuno può offrire qualche consiglio su cosa sto facendo male con xpointer per favore?

Grazie in anticipo.

+0

Se rimuovo gli spazi dei nomi, il precedente funziona, quindi questo sembra essere un problema con XPointer e il modo in cui mi occupo degli spazi dei nomi – Nerdio

+0

Lo schema 'element()' non supporta i nomi qualificati (vedere https: // www.w3.org/TR/xptr-element/). Un nome specificato con 'element()' deve essere un NCName e fa riferimento a un elemento _single_ identificato con un xs: ID di quel nome. Ovviamente non è quello che vuoi. –

risposta

3

ho dilettato con questo un po 'di più, e ha trovato un sacco di esempi sul web che suggeriscono quello che sto facendo è correct.This è ora una versione funzionante ...

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

Questo esempio utilizza un versione di Test1.xml che ha namespace e Test2.xml che non lo fa.

L'output ora assomiglia a questo ....

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

Questo naturalmente è accettabile, sarebbe bello se la linea si rompe tra l'apertura e la chiusura di elemento1 erano ancora lì

+0

Le interruzioni di riga non fanno parte degli elementi, pertanto non è possibile fare in modo di fare riferimento agli elementi. Prova ad aggiungere '--pretty 1' alla riga di comando xmllint:' xmllint --pretty 1 -xinclude Merge.xml'. Questo ancora non riprodurrà la spaziatura originale, ma sembra un po 'più bello. –

0

Questo lavora con e senza spazi dei nomi:

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

anche parse="xml" è di default. Non è necessario specificarlo.