我正在使用xslt 2.0,我有以下示例xml,我想得到两个“header-grey”节点之间的所有“header-lightgray”节点,这里的问题是:我不知道有多少“标题-lightgray“那里。所以我不能使用position()函数。并且每个xsl都不支持break。
<t>
<parent class="header-gray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
...
<parent class="header-gray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-gray"></parent>
</t>
我想通过它们来替换所有节点,header-grey with div和header-lightgray with span。预期的输出是:
<div class="header-gray">
<span class="header-lightgray"/>
<span class="header-lightgray"/>
<span class="header-lightgray"/>
...
</div>
<div class="header-gray">
<span class="header-lightgray"/>
<span class="header-lightgray"/>
<span class="header-lightgray"/>
</div>
那怎么办呢?
感谢任何帮助。
解决方案我想根据Jan Vlcinsky的回答分享:
<xsl:for-each select="/t/parent[@class='header-gray']">
<xsl:variable name="ns1" select="current()/following-sibling::parent"/>
<xsl:variable name="ns2" select="current()/following-sibling::parent[@class='header-gray'][1]/preceding-sibling::parent"/>
<div class="header-gray">
<xsl:for-each select="$ns1[count(.| $ns2)=count($ns2)]">
<span class="header-lightgray"/>
</xsl:for-each>
</div>
</xsl:for-each>
我不验证上面的代码,但它在我的实际代码中是相同的逻辑。 我没有使用xslt 2.0方式,因为我发现我使用的lxml 2.3不支持xslt 2.
答案 0 :(得分:0)
请参阅页面http://gandhimukul.tripod.com/xslt/grouping20.html
底部的“3.位置分组问题”部分您的问题似乎有点重复:How would you find all nodes between two H3's using XPATH?
问题XPath : select all following siblings until another sibling也处理同样的问题。
答案 1 :(得分:0)
此转化:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<t>
<xsl:for-each-group select="*"
group-starting-with="parent[@class='header-gray']">
<div class="header-gray">
<xsl:apply-templates select="current-group()[position() ne 1]"/>
</div>
</xsl:for-each-group>
</t>
</xsl:template>
<xsl:template match="parent">
<span class="{@class}"/>
</xsl:template>
</xsl:stylesheet>
应用于以下XML文档(提供的片段,包装到单个顶部元素中,使其成为格式良好的XML文档):
<t>
<parent class="header-gray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-gray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-lightgray"></parent>
<parent class="header-gray"></parent>
</t>
会产生想要的正确结果:
<t>
<div class="header-gray">
<span class="header-lightgray"/>
<span class="header-lightgray"/>
<span class="header-lightgray"/>
</div>
<div class="header-gray">
<span class="header-lightgray"/>
<span class="header-lightgray"/>
<span class="header-lightgray"/>
</div>
<div class="header-gray"/>
</t>
答案 2 :(得分:-1)
这是一种方法。
当这个XSLT 2.0解决方案:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<t>
<xsl:apply-templates
select="parent[@class = 'header-gray'][following-sibling::*]"/>
</t>
</xsl:template>
<xsl:template match="*[@class = 'header-gray']">
<div class="{@class}">
<xsl:apply-templates
select="
following-sibling::*[@class = 'header-lightgray']
intersect
following-sibling::*[@class = 'header-gray'][1]/
preceding-sibling::*[@class = 'header-lightgray']"/>
</div>
</xsl:template>
<xsl:template match="*[@class = 'header-lightgray']">
<span class="{@class}"/>
</xsl:template>
</xsl:stylesheet>
...应用于提供的XML(包装在顶级元素中以使文档格式正确):
<t>
<parent class="header-gray"/>
<parent class="header-lightgray"/>
<parent class="header-lightgray"/>
<parent class="header-lightgray"/>
<parent class="header-gray"/>
<parent class="header-lightgray"/>
<parent class="header-lightgray"/>
<parent class="header-lightgray"/>
<parent class="header-gray"/>
</t>
...产生了所需的结果:
<t>
<div class="header-gray">
<span class="header-lightgray" />
<span class="header-lightgray" />
<span class="header-lightgray" />
</div>
<div class="header-gray">
<span class="header-lightgray" />
<span class="header-lightgray" />
<span class="header-lightgray" />
</div>
</t>
此解决方案使用XPath 2.0's intersect operation。