Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
XSLT:如何检查多个节点是否应用于所有节点的某个值_Xslt_Xpath_Grouping - Fatal编程技术网

XSLT:如何检查多个节点是否应用于所有节点的某个值

XSLT:如何检查多个节点是否应用于所有节点的某个值,xslt,xpath,grouping,Xslt,Xpath,Grouping,我有以下简化的XML源代码: <?xml version="1.0" encoding="UTF-8"?> <MVKE> <item> <MANDT>025</MANDT> <MATNR>000000000000000551</MATNR> <VMSTA>2</VMSTA> </item> <item> <MANDT>02

我有以下简化的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>

025
000000000000000551
2.
025
000000000000000551
2.
025
000000000000000551
2.
我需要比较
值。如果它们都是“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>

但输出总是很好

<?xml version="1.0" encoding="UTF-8"?>
<list>
<flag>truetruetrue</flag>
</list>

真的

因为
。我也用
上的键尝试过,但在
中也得到了3个值。如何正确比较3,并在
中仅获得一个值?我只是想把事情复杂化吗?

你不需要为每一个
都添加
。假设上下文节点是一个
MVKE
元素(如您的示例中),当所有
VMSTA
元素的字符串值都等于
2
(当存在任何其他值时,以下表达式返回
true
):

这是因为
item/VMSTA[not(.='2')]
隐式转换为布尔值。节点集的布尔值为
true
当且仅当其为非空时。因此,
item/VMSTA[not(.='2')]
只要选择至少一个节点,即存在字符串值不是
2
VMSTA
元素时,它就是
true
。将表达式包装在
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>

只需使用

not(/*/*/VMSTA[not(. = '2')])
如果存在一个元素
/*/*/VMSTA
,其字符串值不同于字符串
“2”
,则此XPath表达式的计算结果为
false()

否则
true()


这可能被称为“双重否定法则”

我建议使用键获取一组节点,这些节点的值与
的值不同。如果该组只有一个节点,则所有值都相同:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*" />
  <xsl:key name="dupes" match="VMSTA" use="."/>

  <xsl:template match="/">
      <xsl:variable name="vmsta-count"
                    select="count(//VMSTA[generate-id() =
                                   generate-id(key('dupes', .))])"/>
      <list>
        <flag>
          <xsl:choose>
            <xsl:when test="$vmsta-count = 1">
              <xsl:text>true</xsl:text>
            </xsl:when>
            <xsl:otherwise>
              <xsl:text>false</xsl:text>
            </xsl:otherwise>
          </xsl:choose>
        </flag>
      </list>
  </xsl:template>
</xsl:stylesheet>

真的
假的
当针对提供的源运行时,会导致:

<?xml version="1.0"?>
<list>
  <flag>true</flag>
</list>

真的
但是,这是一个通用的案例解决方案,不关心实际价值,只关心价值差异


我希望这能有所帮助。

很好的解释和示例。你好,lwburk,谢谢你的好解释和示例+1很好,我有同样的情况,我从来没有想到解决方案会这么简单:)谢谢你Dimitre的解释。我也必须看看XPATH。这是一个很好的替代方案,尽管有点黑客y、 但是,你又怎么能不欣赏一个优雅的黑客:)@MDeSchaepmeester:与其他答案相比,它肯定没有那么直接;至于OP,它肯定没有那么直接。它更一般,可能需要,也可能不需要,但弄清楚它很有趣。
<?xml version="1.0"?>
<list>
  <flag>true</flag>
</list>