首页 > 解决方案 > XSL 不会写 xmlns:xsl?

问题描述

如何在输出中编写 XSL 命名空间?

我正在使用 XSL 分析 XSL 文档并报告它发现的问题,包括复制节点。问题是我无法xmlns:xsl="http://www.w3.org/1999/XSL/Transform"写入输出的根节点,这意味着每次复制xsl:*元素时都会重复它。

其他命名空间似乎不会发生这种情况。例如,采取以下 XSL

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:custom="custom uri" xmlns:custom2="custom2 uri" exclude-result-prefixes="" version="3.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/" name="xsl:initial-template">
        <custom:element xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:element name="custom2:function">
                <xsl:attribute name="name">whatever</xsl:attribute>
            </xsl:element>
            <xsl:element name="custom2:function">
                <xsl:attribute name="name">whatever2</xsl:attribute>
            </xsl:element>
        </custom:element>
    </xsl:template>
</xsl:stylesheet>

当针对任何 XML 文档运行时,我得到了我期望的结果,除了即使我指定它并且显式为空白xmlns:xsl也缺少它......但这很好,它没有在输出中使用。custom:elementexclude-result-prefixes

<custom:element xmlns:custom="custom uri" xmlns:custom2="custom2 uri">
    <custom2:function name="whatever"/>
    <custom2:function name="whatever2"/>
</custom:element>

但是,如果我name="custom2:function"name="xsl:function"这样的方式替换两者......

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:custom="custom uri" xmlns:custom2="custom2 uri" exclude-result-prefixes="" version="3.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="/" name="xsl:initial-template">
        <custom:element xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
            <xsl:element name="xsl:function">
                <xsl:attribute name="name">whatever</xsl:attribute>
            </xsl:element>
            <xsl:element name="xsl:function">
                <xsl:attribute name="name">whatever2</xsl:attribute>
            </xsl:element>
        </custom:element>
    </xsl:template>
</xsl:stylesheet>

然后xmlns:xsl仍然缺失custom:element我得到

<custom:element xmlns:custom="custom uri" xmlns:custom2="custom2 uri">
    <xsl:function xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="whatever"/>
    <xsl:function xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="whatever2"/>
</custom:element>

而不是我想要的:

<custom:element  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:custom="custom uri" xmlns:custom2="custom2 uri">
    <xsl:function name="whatever"/>
    <xsl:function name="whatever2"/>
</custom:element>

如何更改样式表以声明xmlns:xsl="http://www.w3.org/1999/XSL/Transform"我为根节点?

标签: xsltxslt-3.0

解决方案


使用 Saxon 命名空间别名有助于:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:custom="custom-uri" xmlns:custom2="custom2-uri" version="3.0">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl" xmlns:axsl="http://www.w3.org/1999/XSL/Transform-alias"/>
    <xsl:template match="/" name="xsl:initial-template">
        <custom:element xmlns:axsl="http://www.w3.org/1999/XSL/Transform-alias">
            <xsl:element name="xsl:function">
                <xsl:attribute name="name">whatever</xsl:attribute>
            </xsl:element>
            <xsl:element name="xsl:function">
                <xsl:attribute name="name">whatever2</xsl:attribute>
            </xsl:element>
        </custom:element>
    </xsl:template>
</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/gVhEaiX输出

<custom:element xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:custom="custom-uri"
                xmlns:custom2="custom2-uri">
   <xsl:function name="whatever"/>
   <xsl:function name="whatever2"/>
</custom:element>

大多数时候,您只需将命名空间声明放在根元素上,例如

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:custom="custom-uri" xmlns:custom2="custom2-uri" version="3.0"
    xmlns:axsl="http://www.w3.org/1999/XSL/Transform-alias">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl" />
    <xsl:template match="/" name="xsl:initial-template">
        <custom:element>
            <xsl:element name="xsl:function">
                <xsl:attribute name="name">whatever</xsl:attribute>
            </xsl:element>
            <xsl:element name="xsl:function">
                <xsl:attribute name="name">whatever2</xsl:attribute>
            </xsl:element>
        </custom:element>
    </xsl:template>
</xsl:stylesheet>

我不确定您是否要将其限制为某个元素,因此第一个示例在该元素上声明它,然后当然另外在该元素上声明它xsl:namespace-alias是有意义的。


推荐阅读