所以我的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获得所需的输出?
发布于 2015-02-27 22:17:25
正如我在您的问题下面的注释中所说的,没有足够的信息来涵盖所有情况,但通过调整下面的XSLT,您可能可以实现所需的功能。警告:黑客!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>发布于 2015-02-28 01:11:44
XSLT不会在串行输出文件中创建标记,它会在树中创建节点。创建一个元素节点是一个不可分的操作,您不能在不同的时间创建“节点的开始”和“节点的结束”作为独立的操作。因此,对于处理过程的工作方式,您的头脑中有错误的模型,这将使解决问题变得困难。
虽然@Marcin猜测问题出在苹果和橙子上,但我猜问题出在trackparabreak属性上。也许他是对的,我错了,但你的解释太糟糕了,我们只能猜测。
这是一个棘手的问题,我不打算把时间花在一个完整的解决方案上,部分原因是在XSLT 2.0中这样的事情要容易得多,我讨厌把一只手绑在背后工作,部分原因是在需求不明确的情况下编写大量代码是没有意义的。例如,我不知道如何处理没有trackparabreak属性的<p>,因为您的示例中没有这个属性。
解决这类问题的常用技术是同级递归。这里的模型是,在父元素的模板规则中,将-templates应用于第一个子元素(child::*[1]),而在子元素的模板规则中,在处理子元素之后,将-templates应用于下一个同级元素(following-sibling::*[1]);除非遇到中断条件,例如出现trackparabreak,在这种情况下,您将停止同级递归并展开堆栈。
https://stackoverflow.com/questions/28766564
复制相似问题