xslt中的多个条件检查

时间:2014-09-26 03:00:51

标签: xml xslt

我正在使用xslt 2.0,

我有以下xml

<Test>
<Examples>
  <Example id="uniqueId_1">
    <field>test1</field>
  </Example>
  <Example id="uniqueId_2">
    <field>test2</field>
  </Example>
</Examples>

<references>
  <reference ref="example1">
    <value ref="uniqueId_1"/>
  </reference>
  <reference ref="example2">
    <value ref="uniqueId_1"/>
  </reference>
</references>

<destinations>
  <destination id="example1">
    <address> add1 </address>
  </destination>
  <destination id="example2"/>
</destinations>

</Test>

我需要使用xslt 2.0

将其编组为另一个xml

我生成的xml应该看起来像

<Fields>
   <Field  value="test1" address="add1"/>
   <Field  value="test2" address="" />
</Fields>

基本上对于examples中的每一行,我必须查看哪个reference匹配它并从中派生destination。关于这个循环是如何工作的我很困惑。我会在每个for-each元素上执行example但是如何将一个示例ID与多个references进行比较,然后为每个参考多个destinatons进行比较?

1 个答案:

答案 0 :(得分:2)

您正在考虑必要/程序性的术语。这不是XSLT的工作原理。在XSLT中,您不编写命令或循环,使用规则和谓词描述所需的输出。

在这里,您需要一个匹配field元素的规则(“模板”)。在其他条件相同的情况下,将为任何field元素调用此方法。在其中,您描述了您想要的输出。

<xsl:template match="field">

    <!-- emit a Field element -->
    <Field>

        <!-- its "value" attribute is equal to the field element's content -->
        <xsl:attribute name="value" select="."/>

        <!-- compute its `address` attribute -->
        <xsl:attribute name="address">

            <!-- get the id from the parent element (Example) of the field -->
            <xsl:variable name="field_id" select="../@id"/>

现在我举了一个“谓词”的例子。可以使用方括号语法[]过滤/搜索元素。 //符号用整个文档中的所有references元素开始(我们也可以编写/Test/references)。然后我们得到他们所有的reference个孩子,然后用方括号选择那些value孩子的ref属性与我们上面计算的field_id相匹配的人。

            <!-- find reference elt whose "value" child's ref attribute matches -->
            <xsl:variable name="reference" 
                select="//references/reference[value/@ref = $field_id]"/>

            <!-- find the destination whose id matches the reference's ref -->
            <xsl:variable name="destination" 
                select="//destinations/destination[@id = $reference/@ref"/>

            <!-- pull destination's address and set as value of 'address' att -->
            <xsl:value-of select="$destination/address"/>

        </xsl:attribute>
    </Field>

</xsl:template>

为根元素(“/”)编写另一个模板,该模板发出Fields元素并扫描顶级子元素:

<xsl:template match="/">
    <Fields>
        <xsl:apply-children/>
    </Fields>
</xsl:template>

上述内容可以通过使用xsl:key等XSL功能预先构建地图进行优化,但我们会将其保留一段时间。

关于XSLT的注意事项

需要一些时间来了解XSLT。如果您发现自己在XSLT中非常使用for-eachifchoose,那么您可能做错了什么。你可以说循环和条件逻辑是内置在XSLT中的;它为你做到了。或者更确切地说,它是它的生活,它是它的存在理由。如果要以这种方式查看输入元素,则规则“循环”输入元素,并处理适用的输入元素。诸如foo[@id='id']之类的谓词循环“子”并找到与其id等于id的条件相匹配的谓词。