XSL不会写xmlns:xsl?

XSL won't write 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 文档时,我得到了我期望的结果,除了 custom:element 中缺少 xmlns:xsl,即使我指定了它并且 exclude-result-prefixes 明确为空白...不过没关系,输出中未使用它。

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

但是,如果我像这样用name="xsl:function"替换两个name="custom2: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" 我是根节点?

对于 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 上声明它,这样它才有意义。