问题描述
我在使用 xsl 对类似节点进行分组时遇到以下问题:
I have follwing problem in grouping the similer nodes with xsl:
输入:
<?xml version="1.0" encoding="UTF-8"?>
<concept id="ads">
<p>para1 content goes here</p>
<Bullet>1</Bullet>
<Bullet>2</Bullet>
<Bullet>3</Bullet>
<p>para2 content goes here</p>
<Bullet>4</Bullet>
<Bullet>5</Bullet>
<p>para2 content goes here</p>
</concept>
输出应该是:
<?xml version="1.0" encoding="UTF-8"?>
<concept id="ads">
<p>para1 content goes here</p>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<p>para2 content goes here</p>
<ul>
<li>4</li>
<li>5</li>
</ul>
<p>para2 content goes here</p>
</concept>
所有没有作为Bullet"的imideate前面兄弟的Bullet"元素都应该包含在UL"和Li"元素中.
All the "Bullet" element which does not have imideate preceding sibling as "Bullet" should wrap up in "UL" and "Li" elements.
我正在尝试这样的事情,但无法实现结果:
I am trying something like this but not able to achive the result:
<xsl:for-each select="Bullet[not(preceding-sibling::Bullet)]">
<ul>
<xsl:copy-of select="."/>
<xsl:variable name="current-name" select="generate-id(.)"/>
<xsl:for-each select="following-sibling::*[Bullet][generate-id(preceding-sibling::*[Bullet]) = $current-name]">
<xsl:copy-of select="."/>
</xsl:for-each>
</ul>
</xsl:for-each>
请帮忙.
---相关问题----
---Related Question ----
这适用于给定的 xml 输入,但是1. 在我的实际 xml 中,这些 标签可以出现在概念节点下的任何位置,因此在这种情况下,使用
元素分组不起作用.>
This works fine on given xml input, but1. In my actual xml these <Bullet>
tags can appear anywhere under concept node, so grouping with <p>
element does not work in that case.
目前我正在处理除Bullet"节点之外的所有节点,因此我只需要匹配
<Bullet>
节点,该节点的紧随其后为<Bullet>
并将序列包装在
中,将每个包装在
中.我当前的上下文节点是
.
Currently I am processing all the nodes except "Bullet" nodes, so i need to match only
<Bullet>
nodes which is having immediate following sibling as<Bullet>
and wrap the sequence in<ul>
and each<Bullet>
in<li>
. My current context node is<concept>
.
当前样式表如下:
实际的 XML 模式:
Actual XML pattern:
<?xml version="1.0" encoding="UTF-8"?>
<concept id="ads">
<p>para1 content goes here</p>
<Body-text>Body1 content goes here</Body-text>
<Bullet>1</Bullet>
<Bullet>2</Bullet>
<Bullet>3</Bullet>
<Body-text>Body2 content goes here</Body-text>
<p>para2 content goes here</p>
<Bullet>4</Bullet>
<Bullet>5</Bullet>
<p>para3 content goes here</p>
<Bullet>6</Bullet>
<Bullet>7</Bullet>
<Body-text>Body2 content goes here</Body-text>
<Bullet>6</Bullet>
<Bullet>7</Bullet>
</concept>
<concept id="ads">
<p>para1 content goes here</p>
<Body-text>Body1 content goes here</Body-text>
<Bullet>1</Bullet>
<Bullet>2</Bullet>
<Bullet>3</Bullet>
<Body-text>Body2 content goes here</Body-text>
<p>para2 content goes here</p>
<Bullet>4</Bullet>
<Bullet>5</Bullet>
<p>para3 content goes here</p>
<Bullet>6</Bullet>
<Bullet>7</Bullet>
<Body-text>Body2 content goes here</Body-text>
<Bullet>6</Bullet>
<Bullet>7</Bullet>
</concept>
推荐答案
此样式表:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()[1]|@*"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="Bullet[preceding-sibling::node()[1]
[not(self::Bullet)]]">
<ul>
<xsl:call-template name="makeLi"/>
</ul>
<xsl:apply-templates select="following-sibling::node()
[not(self::Bullet)][1]"/>
</xsl:template>
<xsl:template match="Bullet" name="makeLi">
<li>
<xsl:value-of select="."/>
</li>
<xsl:apply-templates select="following-sibling::node()[1]
[self::Bullet]"/>
</xsl:template>
</xsl:stylesheet>
EDIT:只需将以下应用first Bullet
"规则更改为 first next not Bullet
而不是 p
>.
EDIT: Just changing the following applying "first Bullet
" rule to first next not Bullet
instead of p
.
输出(用根元素包装输入以使其格式正确):
Output (wrapping your input with root element to be wellformed):
<concept id="ads">
<p>para1 content goes here</p>
<Body-text>Body1 content goes here</Body-text>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<Body-text>Body2 content goes here</Body-text>
<p>para2 content goes here</p>
<ul>
<li>4</li>
<li>5</li>
</ul>
<p>para3 content goes here</p>
<ul>
<li>6</li>
<li>7</li>
</ul>
<Body-text>Body2 content goes here</Body-text>
<ul>
<li>6</li>
<li>7</li>
</ul>
</concept>
<concept id="ads">
<p>para1 content goes here</p>
<Body-text>Body1 content goes here</Body-text>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
<Body-text>Body2 content goes here</Body-text>
<p>para2 content goes here</p>
<ul>
<li>4</li>
<li>5</li>
</ul>
<p>para3 content goes here</p>
<ul>
<li>6</li>
<li>7</li>
</ul>
<Body-text>Body2 content goes here</Body-text>
<ul>
<li>6</li>
<li>7</li>
</ul>
</concept>
注意:细粒度遍历.
通过分组,这个样式表:
With grouping, this stylesheet:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="concept">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each-group select="*"
group-adjacent="boolean(self::Bullet)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<ul>
<xsl:apply-templates select="current-group()"/>
</ul>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="Bullet">
<li>
<xsl:value-of select="."/>
</li>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
EDIT:使用 group-adjacent
.
这篇关于相似节点的分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!