如何根据您在层次结构中的位置查找XML中的元素

时间:2013-04-04 16:00:51

标签: xslt

我有一个相当复杂的XML结构,但在一小部分中,我有一个以下结构中的输入/输出时间列表以及它可能包含的潜在数据:

<EventSummary>
   <Name>In/Out times</Name>
   <Entries>
      <Entry>
         <Name>In</Name>
         <Time>4/1/2013 10:45</Time>
         <Value>1</Value>
      </Entry>
      <Entry>
         <Name>In</Name>
         <Time>4/1/2013 10:55</Time>
         <Value>1</Value>
      </Entry>
      <Entry>
         <Name>Out</Name>
         <Time>4/1/2013 11:30</Time>
         <Value>0</Value>
      </Entry>
      <Entry>
         <Name>In</Name>
         <Time>4/1/2013 11:35</Time>
         <Value>1</Value>
      </Entry>
   </Entries>
</EventSummary>

因此保证条目按时间顺序排列,但我需要在下一个Out时间内协调一个In time。因此,在上面的示例中,我们有一个In时间,然后是另一个In tim,然后是Out时间,然后是和时间。我需要的最终产品看起来像这样:

<Table>
  <Row>
    <Cell>
      <Text>4/1/2013 10:45</Text>
    </Cell>
    <Cell>
      <Text>4/1/2013 11:30</Text>
    </Cell>
  </Row>
  <Row>
    <Cell>
      <Text>4/1/2013 11:35</Text>
    </Cell>
  </Row>
</Table>

基本上我需要为每个输入/输出对添加一行。所以我需要找到第一个In,然后跳过所有下一个Ins直到第一个Out,然后如果在Out之后找到另一个In开始一个新行......依此类推。

我无法弄清楚如何从循环访问条目时切换到查找In或Out。有任何想法吗?

1 个答案:

答案 0 :(得分:1)

这应该这样做:

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

  <xsl:template match="/">
    <Table>
      <xsl:apply-templates
        select="EventSummary/Entries
                   /Entry[Name = 'In' and 
                          (not(preceding-sibling::Entry) or
                            preceding-sibling::Entry[1]/Name = 'Out')]" />
    </Table>
  </xsl:template>

  <xsl:template match="Entry[Name = 'In']">
    <Row>
      <xsl:apply-templates
        select="Time |
                following-sibling::Entry[Name = 'Out'][1]/Time" />
    </Row>
  </xsl:template>

  <xsl:template match="Time">
    <Cell>
      <Text>
        <xsl:value-of select="." />
      </Text>
    </Cell>
  </xsl:template>
</xsl:stylesheet>

在样本输入上运行时,结果为:

<Table>
  <Row>
    <Cell>
      <Text>4/1/2013 10:45</Text>
    </Cell>
    <Cell>
      <Text>4/1/2013 11:30</Text>
    </Cell>
  </Row>
  <Row>
    <Cell>
      <Text>4/1/2013 11:35</Text>
    </Cell>
  </Row>
</Table>