当特定的子标签使用xslt时,我想结束我的标签

时间:2015-02-27 13:45:28

标签: xml xslt-1.0

所以我的xml内容如下:

原始XML:

 <p id="ACB1234" trackparabreak="true">
   <t>
     <apple>Some texts</apple>          
        <p trackparabreak="true">
            <t> Some texts </t>
        </p>
     <orange>Some Texts</orange>
   </t>
 </p>

期望的输出:

 <p id="ACB1234" trackparabreak="true">
      <t>
        <apple>Some texts</apple>
      </t>
   </p>
   <p trackparabreak="true">
      <t>  Some texts </t>
   </p>
   <p>
      <t>
        <orange> Some Texts </orange>
      <t>
   <p>

我们如何使用xslt-1.0获得所需的输出?

2 个答案:

答案 0 :(得分:0)

就像我在你的问题下面的评论中所说,没有足够的信息来涵盖所有情况,但通过调整下面的XSLT,你可以实现你所需要的。警告:hackery! todo:处理属性并规范空间。

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

<xsl:template match="/">
    <root>
        <xsl:apply-templates/>
    </root>
</xsl:template>

<xsl:template match="p[not(ancestor::p)]">
    <p>
        <t>
            <xsl:apply-templates select="t/apple"/>
        </t>
    </p>
    <xsl:apply-templates select="t/*[not(self::apple)]"/>
</xsl:template>

<xsl:template match="apple">
    <apple>
        <xsl:apply-templates/>
    </apple>
</xsl:template>

<xsl:template match="p[ancestor::p]">
    <p>
        <t>
            <xsl:apply-templates/>
        </t>
    </p>
</xsl:template>

<xsl:template match="orange">
    <p>
        <t>
            <orange>
                <xsl:apply-templates/>
            </orange>
        </t>
    </p>
</xsl:template>

</xsl:stylesheet>

输入:

<p id="ACB1234" trackparabreak="true">
  <t>
    <apple>APPLE TEXT</apple>          
    <p trackparabreak="true">
        <t>PARA INSIDE TEXT</t>
    </p>
    <orange>ORANGE TEXT</orange>
  </t>
</p>

输出:

<root>
  <p>
    <t>
        <apple>APPLE TEXT</apple>
    </t>
  </p>
  <p>
    <t> PARA INSIDE TEXT </t>
  </p>
  <p>
    <t>
        <orange>ORANGE TEXT</orange>
    </t>
  </p>
</root>

答案 1 :(得分:0)

XSLT不会在串行输出文件中创建标记,而是在树中创建节点。创建元素节点是不可分割的操作,您不能在不同时间创建“节点的开始”和“节点的结束”作为独立的操作。因此,你的头脑中有一个错误的模型,关于处理的工作方式,这将使解决问题变得困难。

虽然@Marcin已经猜到问题是关于苹果和橘子,但我猜测它是关于trackparabreak的属性。也许他是对的,我错了,但你已经解释得太糟糕了,我们只能猜测。

这是一个棘手的问题,我不打算花时间在一个完整的解决方案上,部分原因是因为这样的事情在XSLT 2.0中变得如此简单,我讨厌用一只手绑在我背后的工作,部分是因为那里有当要求不明确时,没有必要编写大量代码。例如,我不知道你想要对没有trackparabreak属性的<p>做什么,因为你的例子中没有。{/ p>

这类问题的常用技巧是兄弟递归。这里的模型是在父元素的模板规则中,您将模板应用于第一个子元素(child::*[1]),并在子元素的模板规则中,在处理子元素后,将apply-templates应用于下一个兄弟(following-sibling::*[1]);除非你遇到像trackparabreak这样的休息状态,在这种情况下你会停止兄弟的递归并展开堆栈。