如何迭代文档中的特定名称的每个元素()?

时间:2018-03-11 18:42:44

标签: xml xslt

我有两个输入文件:

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

使用XSLT样式表,我正在尝试创建一个如下所示的图形索引:

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

在我看来,我应该能够将document()功能用于此目的。我尝试使用以下样式表,以及macOS High Sierra系统上预装的xsltproc工具(很可能是古代版本):

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

但是,虽然我可以确认输入了for-each select="ns:document",并且document($file-path)确实找到了该文件(使用--load-trace选项),但完整表达式document($file-path)//figure始终是空。

我可以find examples样式表,当你这样做时显然有用。难道我做错了什么?我有什么选择?

1 个答案:

答案 0 :(得分:2)

您的<figure>元素绑定到xhtml命名空间。

请注意,figure元素具有声明的xhtml名称空间,不带名称空间前缀:

<ns:figures xmlns="http://www.w3.org/1999/xhtml" xmlns:ns="http://localhost/">

您在XSLT中声明了xhtml名称空间,但没有名称空间前缀。如果要在XPath中引用该命名空间中的元素,则必须提供一些前缀。

更改您的XSLT以使用xhtml命名空间的名称空间前缀,并调整您的XPath以使用它:

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