订单很重要时的XSLT处理

时间:2009-03-17 19:01:26

标签: xml xslt

我会承认我是xslt的新手,我正在浏览各种教程和文档,但我有一种情况,我不确定如何查找答案。

基本上就是这个。我有一个看起来像这样的xml文档......

<tag1>
  <tag2>
    foo
  </tag2>
  <tag3>
    bar
   </tag3>

  <tag2>
    goo
  </tag2>
  <tag3>
    mar
  </tag3>
</tag1>

所以这里的问题是订单很重要。 tag2和tag3中的项目组合在一起。也就是说,“foo”和“bar”需要一起处理,“goo”和“mar”也是如此。

我不知道如何在构造中捕获它。也就是说,我可以匹配tag2和tag3,但我不知道如何将它们按顺序排列在一起。

有什么想法吗?

5 个答案:

答案 0 :(得分:4)

如果您的源数据已经按照预期的方式进行排序,这是一种直接的分组方式:

<xsl:apply-templates select="/tag1/*[position() mod 2 = 1]" mode="group"/>

这将模板应用于tag1的每个奇数子元素,而不管名称。您使用模式来限制应用的模板(因为该模板必须匹配*)。在模板中,您可以使用following-sibling搜索轴来获取下一个节点。这给你一些类似的东西:

<xsl:template match="*" mode="group">
   <xsl:variable name="next" select="following-sibling::*[1]"/>
   <group>
      <xsl:copy-of select="."/>
      <xsl:copy-of select="$next"/>
   </group>
</xsl:template>

如果你可以依赖元素名称,那就更简单了:

<xsl:apply-templates select="/tag1/tag2"/>

<xsl:template match="tag2">
   <xsl:variable name="next" select="following-sibling::tag3[1]"/>
   <group>
      <xsl:copy-of select="."/>
      <xsl:copy-of select="$next"/>
   </group>
</xsl:template>

请注意,如果您要对每N个元素进行分组,您可以获得当前元素及其后续N-1兄弟元素的列表:

<xsl:variable name="list" select=". | following-sibling::*[position() &lt; $n]"/>

答案 1 :(得分:2)

凯尔似乎走在了正确的轨道上:

具体来说,如果你只是想获得每对tag2和tag3值,并假设这些值总是在tag1节点中按顺序出现,我会使用XSL,如(非常简单):

<xsl:template match="//tag1">
  <xsl:for-each select="tag2">
    <xsl:value-of select="self::node()" />
    <xsl:value-of select="following-sibling::tag3[1]" />
  </xsl:for-each>
</xsl:template>

答案 2 :(得分:0)

如果您只需要处理所有“tag2”&amp; “tag3”元素按顺序顺序排列,然后您可以在选择它们时将“tag2 | tag3”指定为XPath查询。

如果真的是一个需要处理的单位,那么“tag2”&amp; “tag3”应该在新的父元素下组合在一起。

答案 3 :(得分:0)

我怀疑在单一,直接的选择中这是不可能的。或者,您可以单独处理这些组,

<xsl:apply-templates select="foo|bar"/>
<xsl:apply-templates select="goo|mar"/>

使用匹配所有这些的模板。

答案 4 :(得分:0)

这是一个XSLT 1.0转换,根据它们在文档中的位置,对<tag1>的两个连续子项进行分组。

<xsl:stylesheet version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="tag1">
    <root>
      <xsl:apply-templates select="*[position() mod 2 = 1]" />
    </root>
  </xsl:template>

  <xsl:template match="tag1/*">
    <xsl:variable name="next" select="following-sibling::*[1]" />   
    <together>
      <xsl:value-of select="normalize-space(concat(., $next))" />
    </together>
  </xsl:template>
</xsl:stylesheet>

以下是它的工作原理:

  • <tag1>开始,它输出一个根<root>节点,然后选择那些位于该组开头的<tag1>子节点(position() mod 2 = 1)以进一步处理
  • 对于每个节点,第二个模板输出所选节点的文本内容,并且它跟随兄弟

我的测试输出是:

<root>
  <together>foo bar</together>
  <together>goo mar</together>
</root>