XSLT将源xml元素转换为多个不同的目标xml元素

时间:2015-04-14 19:12:40

标签: xml xslt

这篇文章的标题并没有清楚地解释我想要做什么。我想一个例子可以解释它最好。我有一个源xml文档如下:

<x>
   <a>some data 1</a>
   <a>some data 2</a> 
   <a>some data 3</a> 
   <a>some not needed data 4</a> 
   <a>some not needed data 5</a> 
</x>

我需要将其转换为某些<a>元素(在此示例中,让我们说其值为&#34;某些数据x&#34;)必须放入一个部分(起始部分),但由于此部分只能容纳2个元素,其余部分必须放入另一个部分(结束部分)。在这两个部分之间还有其他不相关的元素。例如:

<starting>
   <a>some data 1</a>
   <a>some data 2</a> 
</starting>
<someOtherXmlElements/>
<someMoreOtherXmlElements/>
<ending>
   <a>some data 3</a> 
</ending>

我在模板中有逻辑,它可以计算出我需要提取的整个集合中的哪些元素(在这个例子中,值为#34;某些数据x&#34;)。 问题是,当我在元素中处理时,我无法分辨元素中已有哪些元素。 如果我可以更新变量,这将是一块蛋糕,但遗憾的是XSLT不允许这样做。 有什么建议? 顺便说一句,输出方案不能改变。

1 个答案:

答案 0 :(得分:0)

这并不是非常优雅,但它确实起到了作用。它使用xslt版本1.0。我用msxsl测试了它。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl" version="1.0"
                >
  <xsl:output omit-xml-declaration="yes" method="xml" indent="yes"/>

  <xsl:template match="/">

    <root>
    <starting>
      <xsl:for-each select="/x/a[substring(text(), 1, 9)='some data']">
        <xsl:if test="position() = 1 or position() = 2">
          <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
          </xsl:copy>
        </xsl:if>
      </xsl:for-each>
    </starting>

    <someOtherXmlElements/>
    <someMoreOtherXmlElements/>
    <ending>
      <xsl:for-each select="/x/a[substring(text(), 1, 9)='some data']">
        <xsl:if test="position() &gt; 2">
          <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
          </xsl:copy>
        </xsl:if>
      </xsl:for-each>
    </ending>
    </root>
  </xsl:template>
</xsl:stylesheet>

我得到了这个输出:

<root>
  <starting>
    <a>some data 1</a>
    <a>some data 2</a>
  </starting>
  <someOtherXmlElements />
  <someMoreOtherXmlElements />
  <ending>
    <a>some data 3</a>
  </ending>
</root>