including an XML file into another XML file


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 3 of 3

Thread: including an XML file into another XML file

Hybrid View

  1. #1
    Join Date
    Apr 2007
    Posts
    1

    found XALAN limitation when including an XML file into another XML file

    Hi all,
    Feel stuck here.
    I've broken my XML file into 3 parts. (The header, content and footer).
    I assemble these XML files by putting the following statement in the beginning of the document main.xml

    <?xml version="1.0"?>
    <?xml-stylesheet type="text/xsl" href="convertToXHTML.xsl"?>
    <!DOCTYPE cd_page [
    <!ENTITY header SYSTEM "header.xml">
    <!ENTITY content SYSTEM "content.xml">
    <!ENTITY footer SYSTEM "footer.xml">
    ]>

    and put &header; ,&footer; and &content; in main.xml file where ever I need these blocks inserted.

    This main.xml file is linked to an XSL file which outputs XHTML.
    When I open main.xml in internet explorer, it is perfectly converted to XHTML but it does not work on firefox.
    So for compatibility with all browsers, I want to do the conversion on the server side and send XHTML output to the browser.
    When I convert it on the server side using java servlets and XALAN API it seems XALAN doesn't support the assembly of the xml blocks in this way (i.e using <!ENTITY) .
    Are there any other methods/approaches of assembling XML blocks. I can test them with XALAN to see wether they are supported or not?
    Last edited by ss596; 04-04-2007 at 04:56 AM. Reason: changed the subject to be more specific

  2. #2
    Join Date
    Apr 2007
    Posts
    15
    You're kind of stuck here. Parsing entities in XSLT is kind of a pain, and some engines (MSXML in SAX mode and Transformiix, Firefox's engine) cut it out entirely for the sake of speed.

    There's XInclude, which is the W3C's recommendation for what you're asking, but it's not very well-implemented yet. However, you have an option: working through/around it using XSLT. If you recall, there's an XSLT-specific document() function that returns an XML file as a node-set, and it works like a charm. Since XInclude elements will be replaced by the included document's content by the time it's parsed, you could work around it with a simple template, like so:

    Code:
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xi="http://www.w3.org/2001/XInclude" exclude-result-prefixes="xi">
      <xsl:template match="xi:include">
        <xsl:apply-templates select="document(@href)/*"/>
      </xsl:template>
    </xsl:stylesheet>
    Look at an example of the usage of <xi:include> at ZVON. All that the previous template does is grabbing the document at the URL in the href attribute, and continuing the template processing from the root element of that external document. While this'll be fairly bulletproof, be careful you're aware of what's going on, because any XPath that you try to reference from the root node (/), while in an externally referenced document, will evaluate to the root node of that document, and not the root node of the top-level parent, as you might think. If you really need this functionality, store the root node in a top-level variable, and you can access it later. (i.e. <xsl:variable name="root" select="/"/> at the very top, then you can use <xsl:value-of select="$root/root-element/@someAttribute"/> later, and it won't look in your included child document for <root-element>.)

    Good luck! Let me know how it works, I haven't used this anywhere for myself yet.
    Last edited by korisu; 04-13-2007 at 06:14 PM.

  3. #3
    Join Date
    Apr 2007
    Posts
    15
    I realized yesterday that this won't quite work as-is... not like it should, anyway. With XInclude, any processor that accesses the document should see the entire document AFTER inclusions, and shouldn't see the <xi:include> elements. If you're using libxslt, there's a pre-process-XInclude directive you can use at runtime, but otherwise, you're SOL. The above will work, but it needs to be included in an identity transform. Then this transform needs to be run BEFORE the task that needs to see the final document, and the transform's output should be fed into that task's input. Here's the final code I came up with:

    xinclude.xsl
    Code:
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xi="http://www.w3.org/2001/XInclude" exclude-result-prefixes="xi">
    	<xsl:include href="no-ns-identity.xsl"/>
    	<xsl:template match="xi:include">
    		<xsl:apply-templates select="document(@href)"/>
    	</xsl:template>
    </xsl:stylesheet>
    no-ns-identity.xsl
    Code:
    <!--
    	This stylesheet copies the document, excluding all namespaces not in use.
    -->
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    	<xsl:template match="@*">
    		<xsl:attribute name="{name()}" namespace="{namespace-uri()}">
    			<xsl:value-of select="."/>
    		</xsl:attribute>
    	</xsl:template>
    	<xsl:template match="*">
    		<xsl:element name="{name()}" namespace="{namespace-uri()}">
    			<xsl:apply-templates select="@*|node()"/>
    		</xsl:element>
    	</xsl:template>
    	<xsl:template match="comment()|processing-instruction()">
    		<xsl:copy-of select="."/>
    	</xsl:template>
    </xsl:stylesheet>
    xinclude-test.xml
    Code:
    <st:test xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:st="http://scott.trenda.net/scotts/crazy/namespace">
    	<head>this is a test of the xinclude broadcast system.</head>
    	<xi:include href="xinclude-test2.xml"/>
    </st:test>
    xinclude-test2.xml
    Code:
    <beeeeeep st:test="test!" xmlns:st="http://scott.trenda.net/scotts/crazy/namespace">this is only a test.</beeeeeep>
    Result of performing xinclude.xsl transform on xinclude-test.xml:
    Code:
    <?xml version="1.0"?>
    <st:test xmlns:st="http://scott.trenda.net/scotts/crazy/namespace">
    	<head>this is a test of the xinclude broadcast system.</head>
    	<beeeeeep st:test="test!">this is only a test.</beeeeeep>
    </st:test>
    From there, you can use that output anywhere else. Remember that you have to perform the xinclude.xsl transform first, if you want the included data to be visible to your next process. Cheers!


    p.s. There are a few other specifications for XInclude over at the official XInclude recommendation; some of them are basic next steps for making a system like this bulletproof, and some of them might not be possible with this system. What I've set up here only provides support for the <xi:include> element, and its href attribute.
    Last edited by korisu; 04-17-2007 at 11:05 AM.

Similar Threads

  1. updating xml file from VB6
    By smithg22 in forum VB Classic
    Replies: 9
    Last Post: 04-12-2005, 06:23 PM
  2. Try XML Junction
    By Tim in forum xml.announcements
    Replies: 0
    Last Post: 10-11-2001, 04:00 PM
  3. File uploading / objFile.Write problem
    By Tomer Cagan in forum ASP.NET
    Replies: 1
    Last Post: 07-24-2001, 09:01 AM
  4. Problem Converting ADO Recordset to XML
    By CHRISTOS STAVRINOU in forum VB Classic
    Replies: 0
    Last Post: 11-16-2000, 04:58 PM
  5. XML Security
    By HSIN NING in forum XML
    Replies: 0
    Last Post: 08-21-2000, 12:17 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center