XSLT 多个输出文件不适用于命名空间

XSLT multiple output files not working with namespace

我正在尝试使用 xslt 2.0

从一个合并的 xml 文件生成多个 html 输出文件

当我在该部分中没有命名空间时,它按预期工作

当我使用 docbook 命名空间时,没有生成任何文件。

有人知道为什么它不能使用名称空间吗?

我的 xsl 文件:

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

    <xsl:output method="text"/>
    <xsl:output method="html" indent="yes" name="html"/>

    <xsl:template match="/">
        <xsl:for-each select="book/chapter/section">
            <xsl:variable name="filename" select="concat('www/out/',@xml:id,'.html')" />
            <xsl:value-of select="$filename" />  <!-- Creating  -->
            <xsl:result-document href="{$filename}" format="html">
                <html><body>
                    <xsl:value-of select="title"/>
                </body></html>
            </xsl:result-document>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

我的xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<book>
    <chapter>
        <section xmlns="http://docbook.org/ns/docbook"  xml:id="lorem_1" >
            <title>Lorem ipsum 1?</title>
        </section>
        <section xmlns="http://docbook.org/ns/docbook" xml:id="lorem_2" >
            <title>Lorem ipsum 2?</title>
        </section>
    </chapter>
</book>

没有

xmlns="http://docbook.org/ns/docbook"

它为我生成了 2 html 个文件

我使用来自 Saxonica 的 Saxon 9.1.0.8J

build.sh

export CLASSPATH=$CLASSPATH:/usr/share/java/saxonb.jar

java net.sf.saxon.Transform -ext:on  -s:www/merged.xml -xsl:www/transform.xsl -T -xi

它不能使用名称空间,因为您没有在 XSLT 中考虑名称空间。您的 XSLT 在没有命名空间的情况下寻找名为 section 的元素,因此不会在命名空间中的 XML 中找到该元素。

如果确实只有 sectiontitle 元素在命名空间中,而不是 bookchapter 元素,您可以通过声明来处理命名空间它在 XSLT 中带有前缀,如下所示:

xmlns:db="http://docbook.org/ns/docbook"

然后在需要的地方使用该前缀 select 该名称空间中的元素:

<xsl:for-each select="book/chapter/db:section">

试试这个 XSLT

<xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:db="http://docbook.org/ns/docbook"
        version="2.0">

    <xsl:output method="text"/>
    <xsl:output method="html" indent="yes" name="html"/>

    <xsl:template match="/">
        <xsl:for-each select="book/chapter/db:section">
            <xsl:variable name="filename" select="concat('www/out/',@xml:id,'.html')" />
            <xsl:value-of select="$filename" />  <!-- Creating  -->
            <xsl:result-document href="{$filename}" format="html">
                <html><body>
                    <xsl:value-of select="db:title"/>
                </body></html>
            </xsl:result-document>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

注意,假设您的 XML 拥有默认命名空间中的所有元素,如下所示:

<book xmlns="http://docbook.org/ns/docbook">
    <chapter>
        <section xml:id="lorem_1" >
            <title>Lorem ipsum 1?</title>
        </section>
        <section xml:id="lorem_2" >
            <title>Lorem ipsum 2?</title>
        </section>
    </chapter>
</book>

那么您可以使用 xpath-default-namespace 来避免使用前缀

<xsl:stylesheet
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xpath-default-namespace="http://docbook.org/ns/docbook"
        version="2.0">

    <xsl:output method="text"/>
    <xsl:output method="html" indent="yes" name="html"/>

    <xsl:template match="/">
        <xsl:for-each select="book/chapter/section">
            <xsl:variable name="filename" select="concat('www/out/',@xml:id,'.html')" />
            <xsl:value-of select="$filename" />  <!-- Creating  -->
            <xsl:result-document href="{$filename}" format="html">
                <html><body>
                    <xsl:value-of select="title"/>
                </body></html>
            </xsl:result-document>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>