Проблема с использованием <xsl:apply-templates/>
;это сокращение от <xsl:apply-templates select="node()" />
, поэтому он выбирает узлы, но не атрибуты.Без каких-либо атрибутов выбранного элемента ваши шаблоны для них просто никогда не будут совпадать.
Вместо этого вам нужно сделать следующее:
<xsl:apply-templates select="@*|node()" />
На самом деле, вы все равно, возможно, захотите использовать здесь «шаблон личности»
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
Кроме того, всопоставление с шаблоном @WeightUOM
вы в настоящее время делаете <xsl:value-of select="@WeightUOM"/>
, но так как вы уже сопоставляете @WeightUOM
, то это ничего не даст, так как оно будет пытаться выбрать атрибут текущего атрибута.Вы должны сделать это, чтобы получить значение текущего атрибута
<xsl:value-of select="."/>
И сделать это, чтобы получить значение родительского элемента
<xsl:value-of select="../text()"/>
Вам также не нужно делать<xsl:element name="{name(.)}">
потому что шаблон, соответствующий *
, создаст содержащий элемент.(И name(.)
получает имя атрибута. В любом случае, вам, вероятно, следовало бы сделать name(..)
здесь.)
Наконец, вам, вероятно, нужны шаблоны, явно совпадающие с дочерними текстовыми узлами, чтобы они не выводились дважды
<xsl:template match="*[@WeightUOM]/text()" />
Попробуйте это XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="*[@WeightUOM]/text()" />
<xsl:template match="*[@VolumeUOM]/text()" />
<xsl:template match="@WeightUOM">
<Weight>
<xsl:value-of select="../text()"/>
</Weight>
<WeightUOM>
<xsl:value-of select="."/>
</WeightUOM>
</xsl:template>
<xsl:template match="@VolumeUOM">
<Volume>
<xsl:value-of select="../text()"/>
</Volume>
<VolumeUOM>
<xsl:value-of select="."/>
</VolumeUOM>
</xsl:template>
</xsl:stylesheet>
Обратите внимание, что нет необходимости использовать xsl:element
, если имя элемента статическое.
Или объединить шаблоны,если тебе нравится ...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="*[@WeightUOM|@VolumeUOM]/text()" />
<xsl:template match="@WeightUOM|@VolumeUOM">
<xsl:element name="{substring-before(name(), 'UOM')}">
<xsl:value-of select="../text()"/>
</xsl:element>
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>