关于xml:在新的父节点/元素中package节点

 2021-04-26 

Wrap nodes in new parent node/element

我正在尝试将<code-text>package在div元素中。

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />

<p>...</p>
<p>...</p>
<code-text ATTRIBUTE="JSON">...</code-text>
<code-text ATTRIBUTE="SOAP">...</code-text>
<p>...</p>
<code-text ATTRIBUTE="JSON">...</code-text>
<code-text ATTRIBUTE="SOAP">...</code-text>
<code-text ATTRIBUTE="JSON">...</code-text>
<code-text ATTRIBUTE="SOAP">...</code-text>
<p>...</p>
<p>...</p>
<code-text ATTRIBUTE="JSON">...</code-text>
<code-text ATTRIBUTE="SOAP">...</code-text>

我已经在该站点上看到了一些建议,但是当我重现他们的解决方案时,它并没有100%起作用。
我得到的最接近的是我如何使用XSLTpackage一组相邻的元素?但是由于某种原因,它也一直在后面添加段落。

所以这基本上就是我所在的地方:

1
2
3
4
5
6
7
8
9
10
11
12
13
<xsl:template match="code-text[@ATTRIBUTE]">
    <xsl:element name="div">
        <xsl:attribute name="class">
            <xsl:text>codes</xsl:text>
        </xsl:attribute>
        <xsl:call-template name="code-text" />
    </xsl:element>
    <xsl:apply-templates select="following-sibling::node()[not(self::code-text[@ATTRIBUTE])][1]" />
</xsl:template>
<xsl:template match="code-text[@ATTRIBUTE][preceding-sibling::node()[1]/self::code-text[@ATTRIBUTE]]" name="code-text">
    <xsl:text>Code goes here: </xsl:text><xsl:value-of select="translate(@ATTRIBUTE, $uppercase, $smallcase)" /><xsl:element name="br" />
    <xsl:apply-templates select="following-sibling::node()[1]/self::code-text[@ATTRIBUTE]" />
</xsl:template>

但是输出:

1
2
3
4
5
6
Code goes here: JSON
Code goes here: SOAP

<p>...</p>
Code goes here :SOAP
<p>...</p>

因此重复了最后一个SOAP及其后的段落。

我要:

1
2
3
4
5
Code goes here: JSON
Code goes here: SOAP

<p>...</p>
etc...etc...etc

更新
要澄清有关重复json / soap / json / soap的信息:

1
2
3
4
<code-text ATTRIBUTE="JSON">...</code-text>
<code-text ATTRIBUTE="SOAP">...</code-text>
<code-text ATTRIBUTE="JSON">...</code-text>
<code-text ATTRIBUTE="SOAP">...</code-text>

我想成为:

1
2
3
4
5
6
Code goes here: JSON
Code goes here: SOAP


Code goes here: JSON
Code goes here: SOAP

而不是:

1
2
3
4
Code goes here: JSON
Code goes here: SOAP
Code goes here: JSON
Code goes here: SOAP


要为每对<code-text ATTRIBUTE="JSON"/><code-text ATTRIBUTE="SOAP"/>创建一个div,您可以简单地执行以下操作:

XSLT 1.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/root">
    <body>
        <xsl:apply-templates select="p | code-text[@ATTRIBUTE='JSON']"/>
    </body>
</xsl:template>

<xsl:template match="code-text">
     
        <xsl:value-of select="." />
        <br/>
        <xsl:value-of select="following-sibling::code-text[1]" />
     
</xsl:template>

</xsl:stylesheet>

应用于以下格式良好的示例输入:

XML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<root>
    <p>a</p>
    <p>b</p>
    <code-text ATTRIBUTE="JSON">c1</code-text>
    <code-text ATTRIBUTE="SOAP">c2</code-text>
    <p>d</p>
    <code-text ATTRIBUTE="JSON">e1</code-text>
    <code-text ATTRIBUTE="SOAP">e2</code-text>
    <code-text ATTRIBUTE="JSON">f1</code-text>
    <code-text ATTRIBUTE="SOAP">f2</code-text>
    <p>g</p>
    <p>h</p>
    <code-text ATTRIBUTE="JSON">i1</code-text>
    <code-text ATTRIBUTE="SOAP">i2</code-text>
</root>

结果将是:

1
2
3
4
5
6
7
8
9
10
11
<body>
   <p>a</p>
   <p>b</p>
   c1<br/>c2
   <p>d</p>
   e1<br/>e2
   f1<br/>f2
   <p>g</p>
   <p>h</p>
   i1<br/>i2
</body>


XSLT 1.0样式表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:output method="html"/>

    <xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
    <xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />

    <xsl:key name="head"
        match="code-text[@ATTRIBUTE][preceding-sibling::*[1][self::code-text[@ATTRIBUTE]]]"
        use="generate-id(preceding-sibling::code-text[not(preceding-sibling::*[1][self::code-text[@ATTRIBUTE]])][1])"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="code-text[not(preceding-sibling::*[1][self::code-text[@ATTRIBUTE]])]">
       
            <xsl:apply-templates select=". | key('head', generate-id())" mode="output"/>
       
    </xsl:template>

    <xsl:template match="code-text[@ATTRIBUTE][preceding-sibling::*[1][self::code-text[@ATTRIBUTE]]]"/>

    <xsl:template match="code-text" mode="output">
        <xsl:text>Code goes here: </xsl:text><xsl:value-of select="translate(@ATTRIBUTE, $uppercase, $smallcase)" /><br/>
    </xsl:template>
</xsl:stylesheet>

转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<body>
    <p>...</p>
    <p>...</p>
    <code-text ATTRIBUTE="JSON">...</code-text>
    <code-text ATTRIBUTE="SOAP">...</code-text>
    <p>...</p>
    <code-text ATTRIBUTE="JSON">...</code-text>
    <code-text ATTRIBUTE="SOAP">...</code-text>
    <code-text ATTRIBUTE="JSON">...</code-text>
    <code-text ATTRIBUTE="SOAP">...</code-text>
    <p>...</p>
    <p>...</p>
    <code-text ATTRIBUTE="JSON">...</code-text>
    <code-text ATTRIBUTE="SOAP">...</code-text>
</body>

变成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
   <p>...</p>

   <p>...</p>

   Code goes here: jsonCode goes here: soap


   <p>...</p>

   Code goes here: jsonCode goes here: soapCode goes here: jsonCode goes here: soap




   <p>...</p>

   <p>...</p>

   Code goes here: jsonCode goes here: soap


</body>