Xml 分组/移动具有相同属性的节点
在stackoverflow和其他网站上阅读了5个小时后,我无法为我的问题创建解决方案。很多描述的问题和解决方案听上去都很熟悉。但不幸的是,我没能把它适应我的需要 我的初始xml文件如下所示:Xml 分组/移动具有相同属性的节点,xml,xslt,Xml,Xslt,在stackoverflow和其他网站上阅读了5个小时后,我无法为我的问题创建解决方案。很多描述的问题和解决方案听上去都很熟悉。但不幸的是,我没能把它适应我的需要 我的初始xml文件如下所示: <document> <page> <block> <line> <span string="String1" bottom="12" /> </line> </blo
<document>
<page>
<block>
<line>
<span string="String1" bottom="12" />
</line>
</block>
<block>
<line>
<span string="String2" bottom="12" />
</line>
</block>
<block>
<line>
<span string="String3" bottom="12" />
</line>
</block>
<block>
<line>
<span string="String4" bottom="20" />
</line>
</block>
<block>
<line>
<span string="String5" bottom="20" />
</line>
</block>
<block>
<line>
<span string="String6" bottom="30" />
</line>
</block>
</page>
<page>
<block>
<line>
<span string="String10" bottom="20" />
</line>
</block>
<block>
<line>
<span string="String11" bottom="20" />
</line>
</block>
<block>
<line>
<span string="String12" bottom="25" />
</line>
</block>
</page>
</document>
<document>
<page>
<block>
<line>
<span string="String1" bottom="12" />
<span string="String2" bottom="12" />
<span string="String3" bottom="12" />
</line>
</block>
<block>
<line>
<span string="String4" bottom="20" />
<span string="String5" bottom="20" />
</line>
</block>
<block>
<line>
<span string="String6" bottom="30" />
</line>
</block>
</page>
<page>
<block>
<line>
<span string="String10" bottom="20" />
<span string="String11" bottom="20" />
</line>
</block>
<block>
<line>
<span string="String12" bottom="25" />
</line>
</block>
</page>
</document>
span
,作为实际块/行
节点下的最后一个节点//块/行
,不包含任何进一步的span
<?xml version="1.0" encoding="UTF8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<!-- Identity - copy all other data-->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//block/line">
<line>
<xsl:apply-templates select="node()|@*" />
<xsl:if test="parent::block/following-sibling::*[1]/line/span/@bottom = span[last()]/@bottom">
<xsl:copy-of select="parent::block/following-sibling::*[1]/line/span" />
<xsl:apply-templates select="parent::block/following-sibling::*[1]/*" />
</xsl:if>
</line>
</xsl:template>
</xsl:stylesheet>
希望任何人都能帮忙!:-) 在XSLT2(或3)中,您可以对每个组使用xsl:,但在XSLT1中,您可以对“Muenchian分组”使用相同的方法(使用一个键来避免在每次迭代中检查同级的性能开销)
您肯定是被xslt 1卡住了吗(因为xslt2:-)通常我使用命令行中的xmlstarlet
来翻译或测试一些东西。不幸的是,它不支持xslt2。但是使用xsltproc
应该没有问题,它可以处理xslt2。因此,当有人提出xslt2解决方案时,我也会很高兴。:-)xsltproc是xslt1only@DavidCarlisle谢谢。我没有把事情搞砸。现在我在网上搜索了一个命令行linux工具。但当您不喜欢Java时,似乎没有启用xslt2的工具可用。无论是libxml2/xslproc还是xmlstarlet似乎都在计划集成:-/Thx大卫。你的解决方案很有效。看来我应该用xslt2热身了。:-)Ups会说:现在不是用xslt2热身的时候。看来我现在得睡觉了
<?xml version="1.0" encoding="UTF8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<!-- Identity - copy all other data-->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="//block/line">
<line>
<xsl:apply-templates select="node()|@*" />
<xsl:if test="parent::block/following-sibling::*[1]/line/span/@bottom = span[last()]/@bottom">
<xsl:copy-of select="parent::block/following-sibling::*[1]/line/span" />
<xsl:apply-templates select="parent::block/following-sibling::*[1]/*" />
</xsl:if>
</line>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:key name="b" match="page//span"
use="concat(generate-id(ancestor::page[1]),' ',@bottom)"/>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="page">
<page>
<xsl:for-each select=".//span[generate-id()=
generate-id(key('b',
concat(generate-id(ancestor::page[1]),' ',@bottom))[1])]">
<block>
<line>
<xsl:apply-templates select="key('b',
concat(generate-id(ancestor::page[1]),' ',@bottom))"/>
</line>
</block>
</xsl:for-each>
</page>
</xsl:template>
</xsl:stylesheet>