XSLT多个输出文件无法使用命名空间

时间:2018-05-30 07:26:21

标签: xml xslt xslt-2.0 saxon docbook

我尝试使用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

1 个答案:

答案 0 :(得分:2)

它不支持名称空间,因为您没有考虑XSLT中的名称空间。您的XSLT在没有名称空间的情况下查找名为section的元素,因此无法在名称空间中的XML中找到该元素。

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

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

然后在需要的地方使用该前缀来选择该命名空间中的元素:

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