计算当前节点的包含特定值的先前兄弟节点

时间:2014-02-27 14:17:27

标签: xml xpath xslt-2.0

我正在编写一个XSLT2.0样式表来将excel生成的xml文件转换为我自己的xml结构。

生成的xml的结构如下:

<Row><Cell><Data>##tablestart##</Data></Cell></Row>
<Row>
   <Cell><Data>1</Data></Cell>
   <Cell><Data>ABC</Data></Cell>
   <Cell><Data>DEF</Data></Cell>
   <Cell><Data>GHI</Data></Cell>
</Row>
<Row>
   <Cell><Data>2</Data></Cell>
   <Cell><Data>AC</Data></Cell>
   <Cell><Data>DF</Data></Cell>
   <Cell><Data>GI</Data></Cell>
</Row>
<Row>
   <Cell><Data>3</Data></Cell>
   <Cell><Data>AB</Data></Cell>
   <Cell><Data>DE</Data></Cell>
   <Cell><Data>GH</Data></Cell>
</Row>
<Row><Cell><Data>##tableclose##</Data></Cell></Row>
 some other rows I do not need...
<Row><Cell><Data>##tablestart##</Data></Cell></Row>...

这会重复多次。

现在我想获取tablestart和tableclose之间的数据。 为此,我创建了一个包含所有行的数组,现在我想为每个元素添加一个属性,确定它是否是一个数据元素(在tablestart和tableclose之间),并通过在以下代码中检查此属性来处理它。 / p>

问题:如何检查它是否在tablestart和tableclose之间?

我期待着阅读你的回答:)

2 个答案:

答案 0 :(得分:0)

这看起来像是一个可以通过XSLT 2.0和for-each-group select="Row" group-starting-with="Row[Cell/Data = '##tablestart##']"来解决的问题:

<xsl:for-each-group select="Row" group-starting-with="Row[Cell/Data = '##tablestart##']">
  <xsl:for-each-group select="current-group()" group-ending-with="Row[Cell/Data = '##tableclose##']">
    <!-- now here current-group()[position() ne last()] selects the elements between start and and -->
  </xsl:for-each-group>
</xsl:for-each-group>

如果第一个Row可能没有Cell/Data = '##tablestart##',意味着在第一个“表格”之前可能有Row个,那么在for-each内部进行额外检查-group是必需的。

答案 1 :(得分:0)

您可以要求XSLT计算每行之前的开始和结束标记的数量。如果开始标记多于结束标记,则表示您位于数据行:

  <xsl:for-each select="//Row">
    <xsl:if test="Cell/Data != '##tableclose##' and count(preceding-sibling::Row[Cell/Data='##tablestart##']) != count(preceding-sibling::Row[Cell/Data='##tableclose##'])">
      Found an internal row at <xsl:value-of select="position()"/>      
    </xsl:if>
  </xsl:for-each>