Несколько выходных файлов XSLT не работают с пространством имен

Я пытаюсь сгенерировать несколько выходных файлов HTML из одного объединенного файла XML с XSLT 2.0

это работает, как и ожидалось, когда у меня нет пространства имен в разделе

когда я использую пространство имен 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-файла

я использую Saxon 9.1.0.8J от Saxonica

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 ответ

Решение

Он не работает с пространствами имен, потому что вы не учли пространство имен в своем XSLT. Вы XSLT ищете элемент под названием section ни в каком пространстве имен, и поэтому не найдет элемент в XML, который находится в пространстве имен.

Если, действительно, только section а также title элементы находятся в пространстве имен, а не book а также chapter также вы можете обработать пространство имен, объявив его с префиксом в 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>
Другие вопросы по тегам