【问题标题】:Comparing values in xml using XSLT foreach loop and determining if they are the same or not使用 XSLT foreach 循环比较 xml 中的值并确定它们是否相同
【发布时间】:2012-06-07 13:10:09
【问题描述】:

我有以下 xml:

<?xml version="1.0" encoding="UTF-8"?>
<abc1 formName="Form">
    <Level1>
        <Element1>ZZZ</Element1>
        <Element2>
            <SubElement1>Apples</SubElement1>
            <SubElement2>Oranges</SubElement2>
            <SubElement3>Pears</SubElement3>
            <SubElement4>Blueberries</SubElement4>
            <SubElement5>Milkshakes</SubElement5>
        </Element2>
    </Level1>
    <Level1>
        <Element1>XXX</Element1>
        <Element2>
            <SubElement1>Apples</SubElement1>
            <SubElement2>Oranges</SubElement2>
            <SubElement3>Kiwifruit</SubElement3>
            <SubElement4>Blueberries</SubElement4>
            <SubElement5>Soda</SubElement5>
        </Element2>
    </Level1>
</abc1>

我需要做的是查看一些节点中的值,确定它们是否不同,如果不同,编写一些不同的 html 代码,每个部分之间有一个分页符。

所以,我需要比较&lt;Element1&gt; 的值,看看它们是否不同。 &lt;Element1&gt; 值可以是任何文本,并且在 xml 中 &lt;Element1&gt;tags 的数量可以是无限的。

所以在这种情况下,我们有两个不同的&lt;Element1&gt; 值:“ZZZ”和“XXX”。

如果有两个'',则如下所示:

<xsl:choose>
<xsl:when test="differentvalues = 'true'">
<!--  SomeHTMLCode!-->
<p style="page-break-after: always"/>
<!--  SomeHTMLCode!-->
</xsl:when>
<xsl:otherwise><!--  SomeHTMLCode!--></xsl:otherwise>
</xsl:choose>

但是使用for循环来搜索xml,和类似的东西

<xsl:choose>
<xsl:when test="differentvalues = 'true'">
<!--  SomeHTMLCode!-->
<p style="page-break-after: always"/>
<!--  SomeHTMLCode!-->
<p style="page-break-after: always"/>
<!--  SomeHTMLCode!-->
</xsl:when>
<xsl:otherwise><!--  SomeHTMLCode!--></xsl:otherwise>
</xsl:choose>

如果存在三个不同的&lt;/Element1&gt; 值。

我什至不确定这是否可以做到。 提前感谢您为我提供的任何帮助。

【问题讨论】:

  • 这不是同样的问题吗?
  • 我想它是相似的,但我使用 xslt 的时间不长,并认为它们有点不同。

标签: xslt foreach compare


【解决方案1】:

此 XPath 表达式为您提供 Element1 的不同值的所需计数(假设 Element1 也不能有后代 Element1(有更有效的方法来处理此类问题,使用钥匙,但我不会谈论新手的钥匙):

count(//Element1[not(. = preceding::Element1)])

您可以在其select 属性中定义一个指定上述值的变量,然后在条件指令的test 属性中使用此变量。

更好的是,根本不使用条件指令并将上述 XPath 表达式指定为模板匹配模式的一部分:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*[count(//Element1[not(. = preceding::Element1)]) = 2]">
     Two processing
 </xsl:template>

 <xsl:template match="/*[count(//Element1[not(. = preceding::Element1)]) = 3]">
     Three processing
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<abc1 formName="Form">
    <Level1>
        <Element1>ZZZ</Element1>
        <Element2>
            <SubElement1>Apples</SubElement1>
            <SubElement2>Oranges</SubElement2>
            <SubElement3>Pears</SubElement3>
            <SubElement4>Blueberries</SubElement4>
            <SubElement5>Milkshakes</SubElement5>
        </Element2>
    </Level1>
    <Level1>
        <Element1>XXX</Element1>
        <Element2>
            <SubElement1>Apples</SubElement1>
            <SubElement2>Oranges</SubElement2>
            <SubElement3>Kiwifruit</SubElement3>
            <SubElement4>Blueberries</SubElement4>
            <SubElement5>Soda</SubElement5>
        </Element2>
    </Level1>
</abc1>

产生想要的正确结果

 Two processing

当对以下 XML 文档应用相同的转换时

<abc1 formName="Form">
    <Level1>
        <Element1>ZZZ</Element1>
        <Element2>
            <SubElement1>Apples</SubElement1>
            <SubElement2>Oranges</SubElement2>
            <SubElement3>Pears</SubElement3>
            <SubElement4>Blueberries</SubElement4>
            <SubElement5>Milkshakes</SubElement5>
        </Element2>
    </Level1>
    <Level1>
        <Element1>YYY</Element1>
        <Element2>
            <SubElement1>Apples</SubElement1>
            <SubElement2>Oranges</SubElement2>
            <SubElement3>Pears</SubElement3>
            <SubElement4>Blueberries</SubElement4>
            <SubElement5>Milkshakes</SubElement5>
        </Element2>
    </Level1>
    <Level1>
        <Element1>XXX</Element1>
        <Element2>
            <SubElement1>Apples</SubElement1>
            <SubElement2>Oranges</SubElement2>
            <SubElement3>Kiwifruit</SubElement3>
            <SubElement4>Blueberries</SubElement4>
            <SubElement5>Soda</SubElement5>
        </Element2>
    </Level1>
</abc1>

再次产生正确的结果

 Three processing

注意

当然,您需要将模板的主体替换为您想要的处理。

【讨论】:

  • 谢谢。这是太棒了。我以前从未见过。如果“级别”的数量未知怎么办?那你有什么可以做的吗?您设置了两个和三个的代码......但如果它未知怎么办?
  • @CooperCripps:此解决方案适用于任意数量的 Level -s 和任何 Level -s 的嵌套。请您接受这个答案(通过单击它旁边的复选标记?
  • 您好 Dimitre,但您列出了两个模板:一个用于“两个处理”,一个用于“三个处理”。可以说我不知道​​是否有“五处理”或“十处理”。如果您只有两个模板,我不明白它如何与任意数量的级别一起工作。对不起,如果这是一个外行的问题。
  • @CooperCripps:我只被你的问题文本引导。如果可能的计数是静态未知的,那么您将在单个模板中拥有一个 &lt;xsl:choose&gt;,其中包含许多 ` 用于您希望以特定方式处理的计数的每个值区间。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-26
  • 1970-01-01
相关资源
最近更新 更多