Я бы не хотел создавать повторяющееся пространство имен в моем выводе XSLT.
(Я использую XSLT для массажа XML, чтобы Microsoft DataContractSerializer счел нужным действительно обработать его. Одна из вещей, которая не нравится DCS, - это определение одного и того же пространства имен несколько раз.)
Я беру все элементы «Характеристики» из-под элемента 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. Однако значение «функция» не будет найдено в исходном XML, это будет некоторый произвольный префикс (обычно «h»). Проблема в том, что если я использую этот XSLT, то пространство имен назначается 2 префиксам в выходном XML: исходное пространство имен из входного XML (обычно «h») и «функция», сгенерированная XSLT. (Хотя действительный XML, это сбивает с толку бедного Microsoft.)
Поэтому я бы хотел полностью избежать определения пространства имен «feature» в выходном XML, вместо этого ссылаясь на пространство имен текущего элемента. Я пробовал варианты на этом, но я не знаю, как правильно установить значение пространства имен элемента xsl: для получения префикса пространства имен текущего узла контекста ...
<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>