本文介绍了相似节点的分组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 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.

  1. 目前我正在处理除Bullet"节点之外的所有节点,因此我只需要匹配 <Bullet> 节点,该节点的紧随其后为 <Bullet> 并将序列包装在

      中,将每个 包装在
    • 中.我当前的上下文节点是 .
  1. 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.

这篇关于相似节点的分组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 06:42