简体   繁体   中英

How to Include one xml file in another xml without root node of source xml file?

As asked in the title, I have two XML files like below structure

A.xml

<Root>
    <J>
        <N>
            //here I want to include B.xml
        </N>
    </J>
</Root>

B.xml

<Root>
    <M></M>
    <O></O>
    <P></P> 
</Root>

I am able to use Xinclude but this is including Root element of B.XML in A.xml also. I want A.xml after including B.xml like below

<Root>
    <J>
        <N>
            <M></M>
            <O></O>
            <P></P>
        </N>
    </J>
</Root>

Please help me out of this.

See here:

https://blogs.gnome.org/shaunm/2011/07/21/understanding-xinclude/

You could do:

<include href="someFile.xml" xpointer="xpointer(/Root/M)"  xmlns="http://www.w3.org/2001/XInclude"/>
<include href="someFile.xml" xpointer="xpointer(/Root/O)"  xmlns="http://www.w3.org/2001/XInclude"/>
<include href="someFile.xml" xpointer="xpointer(/Root/P)"   xmlns="http://www.w3.org/2001/XInclude"/>

May well be better approaches - just introducing an idea.

Alternatively, if you have the option you could try a different xml structure. Could B.xml have "N" as its root note for example?

<N>
    <M> 
    <O> 
    <P>
</N>

Then include file one level up. This may well not be possible of course, N could have other content or you may not be able to change xml structure.

As afrogonabike mentioned, you could use XInclude along with XPointer to select which elements need to be included. Unfortunately XPointer doesn't specify wildcards, and whether they're possible or not depends on the implementation. So unless you know upfront which elements are gonna be in B.xml you're out of luck. There seems to be quite some difference between what from XPoint is supported across implementations, so it could be tricky to get this to work in a somewhat portable or reliable manner.

I suggest you use XSLT instead. XPath is a lot more convenient, and XSLT has a document() function to refer to elements in other documents than the one provided as input. Here's a basis for you to work on:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:output method="xml" />

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="N">
        <xsl:copy>
            <xsl:apply-templates select="document('B.xml')/*/*" />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

By default the stylesheet will copy any nodes and attributes. If it encounters an N element, it's going to copy that element, but instead of processing the contents it will apply the templates to the child elements of the root of the referenced document (B.xml).

Note that this only works if B.xml is at the same location as your input document. If you're not starting from a file but from, say, a stream, you'd have to come up with something else. It's gonna depend on your environment. Depending on the XSLT processor used, you might be able to supply the contents of B as a parameter to the transformation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM