首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在节点之间分组节点?

如何在节点之间分组节点?
EN

Stack Overflow用户
提问于 2015-03-15 00:57:48
回答 4查看 116关注 0票数 2

我知道以前有人回答过这个问题,但我很好奇如何在没有钥匙的情况下实现这个目标。

我有这个XML,我必须得到{%tab%}和{%endtab%}之间的节点。

代码语言:javascript
复制
<element>
  <hello>{%tab%}</hello>
  <hello>yes</hello>
  <hello>{%endtab%}</hello>
  <hello>no</hello>
  <hello>no</hello>
  <hello>{%tab%}</hello>
  <hello>yes</hello>
  <hello>{%endtab%}</hello>
</element>

这就是我得到的:

代码语言:javascript
复制
  <xsl:template match="hello[preceding-sibling::hello[not(normalize-space(text())!='{%tab%}')]]
                     [following-sibling::hello[not(normalize-space(text())!='{%endtab%}')]]
                     [
                     (preceding-sibling::hello[not(normalize-space(text())!='{%tab%}')])[1]/(following-sibling::hello[not(normalize-space(text())!='{%endtab%}')])[1]
                     = (following-sibling::hello[not(normalize-space(text())!='{%endtab%}')])[1]
                     ]">
    <strong><xsl:value-of select="." /></strong>
  </xsl:template>

这将选择所有节点,这些节点后面是{%endtab%},前面是{%tab%}节点。

代码语言:javascript
复制
hello[preceding-sibling::hello[not(normalize-space(text())!='{%tab%}')]]
                         [following-sibling::hello[not(normalize-space(text())!='{%endtab%}')]]

这方面的问题是,"no“节点也被选中,因为它们也位于这些节点之间。因此,我必须确保某个节点后面的{%endtab%} (它的第一次出现)与前面的{%选项卡%}后面的{%选项卡%}相同,这是我对这个XPath所做的:

代码语言:javascript
复制
[
(preceding-sibling::hello[not(normalize-space(text())!='{%tab%}')])[1]
/(following-sibling::hello[not(normalize-space(text())!='{%endtab%}')])[1]
= (following-sibling::hello[not(normalize-space(text())!='{%endtab%}')])[1]
]

但是,这并没有像预期的那样过滤"no“节点。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-03-16 00:29:12

这个XPath表达式

代码语言:javascript
复制
 /*/*[not(. = '{%tab%}' or . = '{%endtab%}') 
    and preceding-sibling::*[. = '{%tab%}' or . = '{%endtab%}'][1] = '{%tab%}'
    and following-sibling::*[. = '{%tab%}' or . = '{%endtab%}'][1] = '{%endtab%}'
     ]

选择顶部元素的子元素,该元素位于具有字符串值{%tab%}的兄弟元素和具有字符串值{%endtab%}的兄弟元素之间。

这里是一个使用简单XSLT转换的运行示例

代码语言:javascript
复制
<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:template match="/">
    <xsl:copy-of select=
    "/*/*[not(. = '{%tab%}' or . = '{%endtab%}') 
        and preceding-sibling::*[. = '{%tab%}' or . = '{%endtab%}'][1] = '{%tab%}'
        and following-sibling::*[. = '{%tab%}' or . = '{%endtab%}'][1] = '{%endtab%}'
         ]"/>
  </xsl:template>
</xsl:stylesheet>

当此转换应用于所提供的源XML文档时,则为。

代码语言:javascript
复制
<element>
  <hello>{%tab%}</hello>
  <hello>yes</hello>
  <hello>{%endtab%}</hello>
  <hello>no</hello>
  <hello>no</hello>
  <hello>{%tab%}</hello>
  <hello>yes</hello>
  <hello>{%endtab%}</hello>
</element>

想要的,正确的结果产生

代码语言:javascript
复制
<hello>yes</hello>
<hello>yes</hello>
票数 2
EN

Stack Overflow用户

发布于 2015-03-15 01:45:35

忽略下面的兄弟姐妹,计算前面的tab和前面的endtab。如果它们不相等,那么您要么是endtab,要么是yes。排除您是endtab的情况。

请允许我不再使用normalize-space(),以使示例更清晰。

代码语言:javascript
复制
<xsl:template match="hello[
    (. != '{%endtab%}')
    and
    (
        count(preceding-sibling::hello[. = '{%tab%}'])
        != count(preceding-sibling::hello[. = '{%endtab%}'])
    )
    ]">
票数 3
EN

Stack Overflow用户

发布于 2015-03-16 03:41:48

两份普遍感兴趣的说明:

1.

我知道以前有人回答过这个问题,但我很好奇如何在没有钥匙的情况下实现这个目标。

使用的解决方案链接如下:

https://stackoverflow.com/a/28179346/3016153

2.

由于XSLT2.0解决方案之前已经有人提出,我建议另一个我认为要简单得多的解决方案:

XSLT2.0

代码语言:javascript
复制
<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/element">
    <xsl:copy>
        <xsl:for-each-group select="hello" group-starting-with="hello[.='{%tab%}']">
            <xsl:for-each-group select="current-group()" group-ending-with="hello[.='{%endtab%}']">
                <xsl:if test="current-group()[self::hello[.='{%tab%}']]">
                    <xsl:for-each select="current-group()[not(position()=1 or position()=last())]">
                        <strong><xsl:value-of select="." /></strong>
                    </xsl:for-each>
                </xsl:if>
            </xsl:for-each-group>
        </xsl:for-each-group>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29056074

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档