我想避免在我的 XSLT 输出中产生重复的命名空间。
(我正在使用 XSLT 处理一些 XML,以便 Microsoft 的 DataContractSerializer 认为适合实际处理它。DCS 似乎不喜欢的一件事是多次定义相同的命名空间。)
我从 XXX 元素下获取所有“Characteristics”元素,并将它们组合在一个新的数组元素中,如下所示:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:feature="some namespace">
<xsl:template match="feature:XXX">
<xsl:copy>
<feature:Characteristics>
<xsl:apply-templates select="feature:Characteristics"/>
</feature:Characteristics>
<xsl:copy-of select="*[not(self::feature:Characteristics)]" />
</xsl:copy>
</xsl:template>
<xsl:template match="feature:Characteristics">
<arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<xsl:value-of select="." />
</arrays:unsignedShort>
</xsl:template>
</xsl:stylesheet>
“功能”名称空间定义在 XSLT 文件的顶部。然而,在源 XML 中不会找到值“feature”,它将是一些任意前缀(通常是“h”)。问题是,如果我使用这个 XSLT,那么命名空间被分配给输出 XML 中的 2 个前缀:来自输入 XML 的原始命名空间(通常是“h”)和由 XSLT 生成的“特征”。(虽然 XML 有效,但这让可怜的 Microsoft 感到困惑。)
所以我想通过引用当前元素的命名空间来完全避免在输出 XML 中定义“功能”命名空间。我对此尝试了变体,但我不知道如何正确设置 xsl:element 的命名空间值以获取当前上下文节点的命名空间前缀......
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:feature="some namespace">
<xsl:template match="feature:XXX">
<xsl:copy>
<xsl:element name="Characteristics" namespace="{???}">
<xsl:apply-templates select="feature:Characteristics"/>
</xsl:element>
<xsl:copy-of select="*[not(self::feature:Characteristics)]" />
</xsl:copy>
</xsl:template>
<xsl:template match="feature:Characteristics">
<arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<xsl:value-of select="." />
</arrays:unsignedShort>
</xsl:template>
</xsl:stylesheet>
样本输入:
<h:XXX xmlns:h="http://stackoverflow.com">
<h:Characteristics>7</h:Characteristics>
<h:Characteristics>11</h:Characteristics>
<h:Characteristics>12</h:Characteristics>
<h:ProductName>blah</h:ProductName>
<h:Vendor>blah</h:Vendor>
<h:Version></h:Version>
</h:XXX>
重复命名空间(坏):
<h:XXX xmlns:h="http://stackoverflow.com">
<feature:Characteristic xmlns:feature="http://stackoverflow.com">
<arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">7</arrays:unsignedShort>
<arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">11</arrays:unsignedShort>
<arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">12</arrays:unsignedShort>
</feature:Characteristic>
<h:ProductName>blah</h:ProductName>
<h:Vendor>blah</h:Vendor>
<h:Version></h:Version>
</h:XXX>
期望的输出:
<h:XXX xmlns:h="http://stackoverflow.com">
<h:Characteristic>
<arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">7</arrays:unsignedShort>
<arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">11</arrays:unsignedShort>
<arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">12</arrays:unsignedShort>
</h:Characteristic>
<h:ProductName>blah</h:ProductName>
<h:Vendor>blah</h:Vendor>
<h:Version></h:Version>
</h:XXX>
这个 XSLT 几乎可以工作,但它涉及硬编码“h”值,我想支持任意值:
<?xml version ="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:feature="some ns"
xmlns:h="some ns"
exclude-result-prefixes="h">
<xsl:template match="feature:XXX">
<xsl:copy>
<h:Characteristic>
<xsl:apply-templates select="feature:Characteristics"/>
</h:Characteristic>
<xsl:copy-of select="*[not(self::feature:Characteristics)]" />
</xsl:copy>
</xsl:template>
<xsl:template match="feature:Characteristics">
<arrays:unsignedShort xmlns:arrays="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<xsl:value-of select="." />
</arrays:unsignedShort>
</xsl:template>
</xsl:stylesheet>