2010-06-07 38 views
3

我正在尝试将XSLT转换应用于一批XML文档。转换的要点是重新排列几个元素。我希望直接之前的元素保留任何意见:xslt&xpath:直接匹配前注释

<!-- not this comment --> 
<element /> 

<!-- this comment --> 
<!-- and this one --> 
<element /> 

我来解决最接近的是使用表达式:

<xsl:template match="element"> 
    <xsl:copy-of select="preceding-sibling::comment()"/> 
</xsl:template> 

其抓住太多的评论:

<!-- not this comment --> 
<!-- this comment --> 
<!-- and this one --> 

我明白为什么上述XPath无法正常工作,但我对如何继续操作没有任何好的想法。我正在寻找的是什么来选择前面的所有意见,其下面的同辈或者是处理其他评论或当前元素:

preceding-sibling::comment()[following-sibling::reference_to_current_element() or following-sibling::comment()] 

回答

5
<xsl:template match="element"> 
    <xsl:copy-of select="preceding-sibling::comment()[ 
    generate-id(following-sibling::*[1]) = generate-id(current()) 
    "/> 
</xsl:template> 

更高效:

<xsl:key 
    name = "kPrecedingComment" 
    match = "comment()" 
    use = "generate-id(following-sibling::*[1])" 
/> 

<!-- ... --> 

<xsl:template match="element"> 
    <xsl:copy-of select="key('kPrecedingComment', generate-id())" /> 
</xsl:template> 
+0

谢谢,您的解决方案完美的作品!我必须对generate-id()和key()进行一些阅读。 – 2010-06-07 16:36:34

+0

@Joshua Johnson:关键:我已经写了一些解释他们如何处理JavaScript示例的东西,请看看你是否想要:http://stackoverflow.com/questions/948218/xslt-3-level- grouping-on-attributes/955527#955527(只读了答案的下半部分)。 – Tomalak 2010-06-07 16:49:40

1

我想最好的方式如下:

我想预先评论,但只有那些与当前节点作为第一个元素来跟随他们。

然后,在xpath1.0/xslt1.0:

<xsl:template match="element"> 
<xsl:copy-of select="preceding-sibling::comment()[count(following-sibling::*[1]|current()) = 1]"/> 
</xsl:template> 
+0

+1 - 但这没有一个简短的解释*为什么*它的工作原理。 ;-) – Tomalak 2010-06-07 16:51:20

+1

@Tomalak:你说得对。对不起!节点集中的每个节点都是disctint(节点集中没有重复的“节点引用”)。因此,为了检查两个节点实际上是同一个节点,您不需要generate-id()函数(将一个节点的唯一id字符串保存到同一个转换过程中)。您只需检查联合产生一个节点集合与一个节点。这是一种减少身份节点集表达式的方法:“count($ a | $ b)= count($ b)和count($ b)= count($ a)”。对不起翻译,我的语言是西班牙语。 – 2010-06-07 17:21:54