具体顺序,需要从XSL订购而不是从输入xml格式

时间:2013-09-10 13:58:54

标签: xslt xml-parsing

我在同一级别和特定顺序遇到同名节点的问题。我的订单取决于他们的节点的价值。我的输出应该是一个txt文件。我的XML看起来像:

<?xml version="1.0" encoding="UTF-8"?>
<header>
  <B>
    <element>
      <value>10</value>
      <value>test</value>
    </element>
  </B>

  <A>
    <element>
      <value>100</value>
      <value>message</value>
    </element>
  </A>
  <B>
    <element>
      <value>20</value>
      <value>phase</value>
    </element>
  </B>

  <A>
    <element>
      <value>101</value>
      <value>type</value>
    </element>
  </A>
  <B>
    <element>
      <value>20</value>
      <value>phase</value>
    </element>
  </B>

  <A>
    <element>
      <value>101</value>
      <value>type</value>
    </element>
  </A>
</header>

我的txt输出应该是这样的。

typephase typephase

等等。

我的XSL看起来像那样

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text" indent="yes" />
<xsl:template match="header/*">

        <xsl:if test="name(.) = 'A' and element/value='101'">
            <xsl:value-of select="element/value[position()=2]" />
        </xsl:if>
        <xsl:if test="name(.) = 'B' and element/value='20'">
            <xsl:value-of select="element/value[position()=2]" />
        </xsl:if>
        <xsl:text>&#xa;</xsl:text>      
</xsl:template>

<xsl:template match="/">
    <xsl:apply-templates select="header/*"></xsl:apply-templates>
</xsl:template>

这个XSL的结果是:

phasetype phasetype

xsl:sort descending对我没有帮助,因为原始输入XML有更多的节点。我需要来自XSL的订单而不是来自输入XML文档的订单。有谁知道,如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

我假设输入XML总是按照 B A B A ... 的顺序包含元素,并且您没有缺少元素。我还假设您只希望 A B 元素成对出现,如果它们都具有正确的值。

这个XSLT样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <!-- Match the root element and apply-templates to all its child elements. -->
  <xsl:template match="header">
    <xsl:apply-templates/>
  </xsl:template>

  <!-- Find A elements with a value of 101, where the B element just before has a value of 20. -->
  <xsl:template match="A[element/value='101'][preceding-sibling::B[1][element/value='20']]">
    <xsl:value-of select="element/value[2]"/>
    <xsl:value-of select="preceding-sibling::B[1]/element/value[2]"/>
    <xsl:text> </xsl:text>
  </xsl:template>

  <!-- Don't do anything with other A elements. -->
  <xsl:template match="A"/>

  <!-- Don't do anything else with B elements. -->
  <xsl:template match="B"/>

</xsl:stylesheet>

应用于以下XML时:

<?xml version="1.0" encoding="UTF-8"?>
<header>
  <B>
    <element>
      <value>10</value>
      <value>test1</value>
    </element>
  </B>
  <A>
    <element>
      <value>100</value>
      <value>message1</value>
    </element>
  </A>
  <B>
    <element>
      <value>20</value>
      <value>phase2</value>
    </element>
  </B>
  <A>
    <element>
      <value>101</value>
      <value>type2</value>
    </element>
  </A>
  <B>
    <element>
      <value>20</value>
      <value>phase3</value>
    </element>
  </B>
  <A>
    <element>
      <value>101</value>
      <value>type3</value>
    </element>
  </A>
</header>

生成此输出:

type2phase2 type3phase3 

我已经为您示例中的value元素添加了数字,以便更清楚输出的内容。