Frage

I have this XML file:

<?xml version="1.0"?>
<xi:include href="http://www.w3schools.com/dom/books.xml" 
            xmlns:xi="http://www.w3.org/2003/XInclude"/>

and I expected that it should result in referenced remote XML file http://www.w3schools.com/dom/books.xml at the time of processing.

For that purpose I created this XSL file:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml"/>
    <xsl:template match="*">
        <xsl:copy-of select="//book/title"/>
    </xsl:template>
</xsl:stylesheet>

which after XSL transform, I expected to get XML output with title nodes from referenced XML file.

However it didn't happen, transformation just produced an empty file. I suspect that XInclude instruction wasn't performed.

So how can I apply XSLT on Xincluded XML file, if possible?

War es hilfreich?

Lösung

In comments, the OP has asked for a walk-through of my referenced answer at Copy xml document's images in different source locations into single output directory , so here it is.

This template..

<xsl:template match="xi:include[@href][@parse='xml' or not(@parse)][fn:unparsed-text-available(@href)]">
 <xsl:apply-templates select="fn:document(@href)" />
</xsl:template>

... matches the xi:include elements that meet all these requirements:

  1. Has a href attribute
  2. It refers to an xml document (as opposed to a text document)
  3. And that document can be found and is openable.

When these conditions are met, open the XML document and process it just as if it was in place here, instead of the xi:include node.

This template ...

<xsl:template match="xi:include[@href][@parse='text'][fn:unparsed-text-available(@href)]">
 <xsl:apply-templates select="fn:unparsed-text(@href,@encoding)" />
</xsl:template>

... does a similar thing for pure text includes. Note the default value for @parse is 'xml'. Note we can even change character encoding. Our main document could be in UTF-8, but the included document may well be UTF-16LE for example.

And finally this template...

<xsl:template match="xi:include[@href][@parse=('text','xml') or not(@parse)][not(fn:unparsed-text-available(@href))][xi:fallback]">
 <xsl:apply-templates select="xi:fallback/text()" />
</xsl:template>

... handles the cases where we can open the document (maybe the file reference is broken), and the xi:include node gives us some fall-back content.

Andere Tipps

XInclude processing, like XSD validation, is something that happens if you ask for it, and not otherwise. The way you ask for it depends on the environment you are in. For example, the Xerces parser has options to do XInclude processing.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top