我正在使用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
进行比较?
答案 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中非常使用for-each
或if
或choose
,那么您可能做错了什么。你可以说循环和条件逻辑是内置在XSLT中的;它为你做到了。或者更确切地说,它是它的生活,它是它的存在理由。如果要以这种方式查看输入元素,则规则“循环”输入元素,并处理适用的输入元素。诸如foo[@id='id']
之类的谓词循环“子”并找到与其id等于id
的条件相匹配的谓词。