Pet*_*ter 3 xslt grouping xpath
我有以下简化的XML源:
<?xml version="1.0" encoding="UTF-8"?>
<MVKE>
<item>
<MANDT>025</MANDT>
<MATNR>000000000000000551</MATNR>
<VMSTA>2</VMSTA>
</item>
<item>
<MANDT>025</MANDT>
<MATNR>000000000000000551</MATNR>
<VMSTA>2</VMSTA>
</item>
<item>
<MANDT>025</MANDT>
<MATNR>000000000000000551</MATNR>
<VMSTA>2</VMSTA>
</item>
</MVKE>
Run Code Online (Sandbox Code Playgroud)
我需要比较这些<VMSTA>值.如果它们都是"2",那么我在目标XML中的标志值应该说"true"否则为"false".
我想出了这个XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes" method="xml" encoding="UTF-8"/>
<xsl:template match="/">
<list>
<xsl:apply-templates select="MVKE"/>
</list>
</xsl:template>
<xsl:template match="MVKE">
<flag>
<xsl:for-each select="item">
<xsl:choose>
<xsl:when
test="(preceding-sibling::*[1]/VMSTA or self::*/VMSTA = current()/VMSTA) and (current()/VMSTA='2')">
<xsl:value-of select="'true'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="'false'"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</flag>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
但输出总是如此
<?xml version="1.0" encoding="UTF-8"?>
<list>
<flag>truetruetrue</flag>
</list>
Run Code Online (Sandbox Code Playgroud)
因为<xsl:for-each>.我也尝试过按键,<VMSTA>但也给了我3个值<flag>.如何正确比较3并且只获得一个值<flag>?我只是想复杂化吗?
你不需要for-each.假设上下文节点是一个MVKE元素(如示例所示),true当所有VMSTA元素的字符串值等于2(以及false存在任何其他值时)时,以下表达式返回:
not(item/VMSTA[not(.='2')])
Run Code Online (Sandbox Code Playgroud)
这是因为隐式转换item/VMSTA[not(.='2')]为布尔值.节点集的布尔值是true且仅当它是非空的时.因此,item/VMSTA[not(.='2')]是true每当它选择至少一个节点,也就是当存在一个VMSTA元件,其字符串值不是2.包装表达式not()会产生否定,这是期望的结果.
完整的例子:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes" method="xml" encoding="UTF-8"/>
<xsl:template match="/">
<list><xsl:apply-templates select="MVKE"/></list>
</xsl:template>
<xsl:template match="MVKE">
<flag><xsl:value-of select="not(item/VMSTA[not(.='2')])"/></flag>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)