Как отфильтровать ненужные узлы после узлов с определенным атрибутом?
XML файл:
<a>
<Item key="1">
<c1>
<d11>
</d11>
<d12 value="1" />
<d13 />
</c1>
</Item>
<b2>
<Item key="fix">
<d21>
</d21>
<d22 value="yes" />
<d23 />
</Item>
</b2>
<b3>
<c3>
<d31>
</d31>
<Item key="price">
<e2 value="no" />
<e3 />
</Item>
</c3>
</b3>
</a>
Файл .xsl:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:param name="element-name">Item</xsl:param>
<xsl:template match="/">
<xsl:for-each select="//*[name()=$element-name]">
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="name()"/>
<xsl:if test="position() != last()">
<xsl:text>/</xsl:text>
</xsl:if>
<xsl:if test ="name()=$element-name">
<xsl:text>[@key='</xsl:text>
<xsl:value-of select="@key"/>
<xsl:text>']/</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="descendant::*">
<xsl:value-of select="name()"/>
<xsl:if test="position() != last() and not(@value)">
<xsl:text>/</xsl:text>
</xsl:if>
<xsl:if test="(.)[@value]">
<xsl:text>/@value</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
После преобразования хочу получить такие данные:
a/Item[@key='1']/c1/d11/d12/@value
a/b2/Item[@key='fix']/d21/d22/@value
a/b3/c3/Item[@key='price']/e2/@value
Но получились такие данные после трансформации:
a/Item[@key='1']/c1/d11/d12/@valued13
a/b2/Item[@key='fix']/d21/d22/@valued23
a/b3/c3/Item[@key='price']/e2/@valuee3
Как отфильтровать ненужные узлы после узлов с атрибутом @value?
Ответы (1 шт):
Автор решения: Alexander Petrov
→ Ссылка
Я просто убрал лишний код:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="//*[@value]">
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="name()"/>
<xsl:text>/</xsl:text>
</xsl:for-each>
<xsl:text>@value </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Результат:
a/Item/c1/d12/@value
a/b2/Item/d22/@value
a/b3/c3/Item/e2/@value
При необходимости, можно вернуть на место код, выводящий атрибут у элемента Item:
<xsl:if test ="name()='Item'">
<xsl:text>[@key='</xsl:text>
<xsl:value-of select="@key"/>
<xsl:text>']/</xsl:text>
</xsl:if>