Несколько выходных файлов 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>