Reputation: 138051
I have two input files:
<!-- index.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<ns:index xmlns:ns="http://localhost/">
<ns:document>test.xml</ns:document>
</ns:index>
<!-- test.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<ns:test xmlns="http://www.w3.org/1999/xhtml" xmlns:ns="http://localhost/">
<div><figure id="fig-1-1">Figure 1-1</figure></div>
<figure id="fig-1-2">Figure 1-2</figure>
</ns:test>
Using an XSLT stylesheet, I'm trying to create a figure index that would look like this:
<?xml version="1.0" encoding="UTF-8"?>
<ns:figures xmlns="http://www.w3.org/1999/xhtml" xmlns:ns="http://localhost/">
<figure id="fig-1-1">test.xml</figure>
<figure id="fig-1-2">test.xml</figure>
</ns:figures>
It seemed to me that I should be able to use the document()
function for this purpose. I tried using the following stylesheet, and the (most likely ancient version of) xsltproc tool that comes preinstalled on macOS High Sierra systems:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://localhost/">
<xsl:template match="/ns:index">
<ns:figures>
<xsl:for-each select="ns:document">
<xsl:variable name="file-path"><xsl:value-of select="text()"/></xsl:variable>
<xsl:for-each select="document($file-path)//figure">
<ns:figure>
<xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
<xsl:value-of select="$file-path"/>
</ns:figure>
</xsl:for-each>
</xsl:for-each>
</ns:figures>
</xsl:template>
</xsl:stylesheet>
However, while I can confirm that for-each select="ns:document"
is entered, and that document($file-path)
does find the file (using the --load-trace
option), the full expression document($file-path)//figure
is always empty.
I can find examples of stylesheets that apparently work when you do this. Am I doing something wrong? What are my options here?
Upvotes: 1
Views: 24
Reputation: 66723
Your <figure>
elements are bound to the xhtml namespace.
Note that the figures element has the xhtml namespace declared without a namespace-prefix:
<ns:figures xmlns="http://www.w3.org/1999/xhtml" xmlns:ns="http://localhost/">
You have the xhtml namespace declared in your XSLT, but without a namespace-prefix. You must provide some prefix if you want to refer to elements from that namespace in XPath.
Change your XSLT to use a namespace-prefix for the xhtml namespace, and adjust your XPath to use it:
<xsl:stylesheet
version="1.0"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns="http://localhost/">
<xsl:template match="/ns:index">
<ns:figures>
<xsl:for-each select="ns:document">
<xsl:variable name="file-path"><xsl:value-of select="text()"/></xsl:variable>
<xsl:for-each select="document($file-path)//xhtml:figure">
<ns:figure>
<xsl:attribute name="id"><xsl:value-of select="@id"/></xsl:attribute>
<xsl:value-of select="$file-path"/>
</ns:figure>
</xsl:for-each>
</xsl:for-each>
</ns:figures>
</xsl:template>
</xsl:stylesheet>
Upvotes: 2