我正在编写一个 XSLT 转换,我希望在根元素上定义所有命名空间前缀。默认情况下,MS 似乎会在 XML 层次结构中的第一个元素上创建一个新的前缀定义以使用该模式。这意味着如果这些元素与同一模式的共享祖先不相关,则可以在多个元素上引用相同的模式。
通过像这样对根元素进行编码,所有工作都按预期工作:
<!-- ... -->
<ns0:root xmlns:ns0="http://some/schema" xmlns:ns1 = "http://another/schema">
<!-- rest of XSLT; including calls to other templates -->
</ns0:root>
<!-- ... -->
但是我找不到任何方法来使用xsl:element
; 例如
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://some/schema"
xmlns:ns1 = "http://another/schema"
>
<!-- ... -->
<xsl:element name="ns0:root">
<xsl:attribute name="ns1" namespace="http://www.w3.org/2000/xslns/">http://another/schema</xsl:attribute>
<!-- rest of XSLT; including calls to other templates -->
</xsl:element>
<!-- ... -->
xls:element
是否可以针对除该元素本身之外的模式声明命名空间前缀?
完整示例
XML
<Demo xmlns="http://some/schema">
<a>Hello</a>
<b>World</b>
</Demo>
XSLT
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://some/schema"
xmlns:ns1 = "http://another/schema"
exclude-result-prefixes="xsl"
>
<xsl:output method="xml" indent="yes" version="1.0"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
<xsl:apply-templates select="@* | node()" />
</xsl:element>
</xsl:template>
<xsl:template match="/ns0:Demo/ns0:a">
<xsl:element name="ns1:z">
<xsl:value-of select="./text()" />
</xsl:element>
</xsl:template>
<xsl:template match="/ns0:Demo/ns0:b">
<xsl:element name="ns1:y">
<xsl:value-of select="./text()" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
结果
<Demo xmlns="http://some/schema">
<ns1:z xmlns:ns1="http://another/schema">Hello</ns1:z>
<ns1:y xmlns:ns1="http://another/schema">World</ns1:y>
</Demo>
期望的结果
<Demo xmlns="http://some/schema" xmlns:ns1="http://another/schema">
<ns1:z>Hello</ns1:z>
<ns1:y>World</ns1:y>
</Demo>
或者
<ns0:Demo xmlns:ns0="http://some/schema" xmlns:ns1="http://another/schema">
<ns1:z>Hello</ns1:z>
<ns1:y>World</ns1:y>
</ns0:Demo>