我正在尝试将“test”元素添加到树的最后一个元素中,但它会为每个元素重复:
<root>
<Module>
<Router>
<Message>@OppositeMacAddress='0x00, 0x80, 0xC8, 0x3B, 0xC6, 0xA0'</Message>
@OppositeMacAddress='0x00, 0x80, 0xC8, 0x3B, 0xC6, 0xA0'
</Router>
@OppositeMacAddress='0x00, 0x80, 0xC8, 0x3B, 0xC6, 0xA0'
</Module>
</root>
这是我的XML源
<fired-rule context="Message[@Name='SPY_IN']"/>
<failed-assert
test="@OppositeIpAddress='192,168,1,2'"
location="/Module[1]/Router[1]/Message[1]">
<text>!Error! Erwarteter Wert:"192,168,1,2"</text>
</failed-assert>
它应该是这样的:
<root>
<Module>
<Router>
<Message>@OppositeMacAddress='0x00, 0x80, 0xC8, 0x3B, 0xC6, 0xA0'</Message>
</Router>
</Module>
</root>
这是我的XSL转换
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="//failed-assert/@location" />
</root>
</xsl:template>
<xsl:template match="@location">
<xsl:param name="path" select="." />
<xsl:variable
name="currentContext"
select="substring-before(substring-after($path,'/'), '[')"/>
<xsl:variable name="subContext" select="substring-after($path, ']')"/>
<xsl:element name="{$currentContext}">
<xsl:apply-templates select="current()[string($subContext)]">
<xsl:with-param name="path" select="$subContext"/>
</xsl:apply-templates>
<xsl:value-of select="../@test"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我该如何解决这个问题?
答案 0 :(得分:1)
在xsl:element
:
<xsl:variable name="next" select="current()[string($subContext)]" />
<xsl:apply-templates select="$next">
<xsl:with-param name="path" select="$subContext"/>
</xsl:apply-templates>
<xsl:value-of select="../@test[not($next)]"/>
完整XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="//failed-assert/@location" />
</root>
</xsl:template>
<xsl:template match="@location">
<xsl:param name="path" select="." />
<xsl:variable name="currentContext"
select="substring-before(substring-after($path,'/'), '[')"/>
<xsl:variable name="subContext" select="substring-after($path, ']')"/>
<xsl:element name="{$currentContext}">
<xsl:variable name="next" select="current()[string($subContext)]" />
<xsl:apply-templates select="$next">
<xsl:with-param name="path" select="$subContext"/>
</xsl:apply-templates>
<xsl:value-of select="../@test[not($next)]"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
运行样本输入时的结果:
<root>
<Module>
<Router>
<Message>@OppositeIpAddress='192,168,1,2'</Message>
</Router>
</Module>
</root>
答案 1 :(得分:1)
我认为更容易理解的解决方案可能是使用call-template。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/">
<root>
<xsl:apply-templates select="//failed-assert[@location]" />
</root>
</xsl:template>
<xsl:template match="failed-assert">
<xsl:call-template name="location">
<xsl:with-param name="path" select="substring-after(@location, '/')" />
<xsl:with-param name="textmessage" select="@test" />
</xsl:call-template>
</xsl:template>
<xsl:template name="location">
<xsl:param name="path" />
<xsl:param name ="textmessage" />
<xsl:variable name="currentContext"
select="substring-before($path,'[')"/>
<xsl:variable name="subContext" select="substring-after($path, '/')"/>
<xsl:choose>
<xsl:when test="$currentContext">
<xsl:element name="{$currentContext}">
<xsl:call-template name="location">
<xsl:with-param name="path" select="$subContext" />
<xsl:with-param name="textmessage" select="$textmessage" />
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$textmessage"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>