XSLT 出力で名前空間が繰り返されるのを避けたいと考えています。
(Microsoft の DataContractSerializer が実際に適切に処理するのに適していると判断できるように、XSLT を使用して一部の XML を処理しています。DCS が気に入らないと思われることの 1 つは、同じ名前空間を複数回定義することです。)
XXX要素の下からすべての「特性」要素を取得し、次のように新しい配列要素にグループ化しています。
<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>
"feature" 名前空間は、XSLT ファイルの先頭で定義されています。ただし、値 "feature" はソース XML には含まれず、任意のプレフィックス (通常は "h") になります。問題は、この XSLT を使用すると、名前空間が出力 XML の 2 つのプレフィックスに割り当てられることです。入力 XML の元の名前空間 (通常は "h") と、XSLT によって生成される "feature" です。(有効な 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>