分组文本节点和特定类型的相邻元素
Grouping text node and adjacent elements of particular type
请建议如何将文本节点和一些元素(如“i
”或“b
”或“list
”分组到“p
”元素中.确保 div
不应该成为 p
.
XML:(带有换行符或空格以供显示,运行 在第 2 个 XML 下方使用)
<article>
<body>
<para>
<display><fig>Fig1</fig></display>
the text node1
</para>
<para>
<display><fig>Fig1</fig></display>
</para>
<para>
<display><fig>Fig1</fig></display>
the text node1 <i>h</i> ther <b>b</b> the text4
<display><tab>Table1</tab></display>
the text node2
<list><li>list1</li></list>
</para>
<para>The text node3</para>
</body>
</article>
XML:(没有换行符)
<article><body><para><display><fig>Fig1</fig></display>the text node1</para><para><display><fig>Fig1</fig></display></para><para><display><fig>Fig1</fig></display>the text node1 <i>h</i> ther <b>b</b> the text4<display><tab>Table1</tab></display>the text node2<list><li>list1</li></list></para><para>The text node3</para></body></article>
XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
<xsl:template match="para">
<xsl:choose>
<xsl:when test="not(text())"><xsl:apply-templates/></xsl:when>
<xsl:when test="display and text() or *">
<xsl:for-each select="node()">
<xsl:choose>
<xsl:when test="name()='display'"><div><xsl:apply-templates/></div></xsl:when>
<xsl:when test="name()='i' or name()='b'">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:when>
<xsl:when test="not(*)"><p><xsl:value-of select="."/></p></xsl:when><!--Here grouping required with adjacent elements 'i' or 'b' etc -->
<xsl:otherwise><p><xsl:apply-templates/></p></xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<p><xsl:apply-templates/></p>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
所需结果:
<article>
<body>
<div><fig>Fig1</fig></div><!--ensure div should not child to 'p'-->
<p>the text node1</p> <!--Text area including 'i' and 'b' to be within 'p' -->
<div><fig>Fig1</fig></div>
<div><fig>Fig1</fig></div>
<p>the text node1 <i>h</i> ther <b>b</b> the text4</p><!--Text area including 'i' and 'b' to be within 'p' -->
<div><tab>Table1</tab></div>
<p>the text node2<list><li>list1</li></list></p><!--text area includes 'list' element -->
<p>The text node3</p>
</body>
</article>
当您使用 XSLT 2.0 时,您可以在此处使用 xsl:for-each-group
,根据相邻子节点是否为 display
元素对它们进行分组。
<xsl:for-each-group select="node()" group-adjacent="boolean(self::display)">
因此,除 display
之外的节点将具有 false
的分组键,因此被分组在一起,允许您将它们包装在 p
标签中
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
<xsl:template match="para">
<xsl:for-each-group select="node()" group-adjacent="boolean(self::display)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:apply-templates select="current-group()" />
</xsl:when>
<xsl:otherwise>
<p>
<xsl:apply-templates select="current-group()" />
</p>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="display">
<div>
<xsl:apply-templates />
</div>
</xsl:template>
</xsl:stylesheet>
我想你可以使用 for-each-group group-adjacent="boolean(self::text() | self::i |.."
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="para">
<xsl:for-each-group select="node()" group-adjacent="boolean(self::text() | self::i | self::b | self::list)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<p>
<xsl:apply-templates select="current-group()"/>
</p>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="display">
<div>
<xsl:apply-templates/>
</div>
</xsl:template>
</xsl:stylesheet>
请建议如何将文本节点和一些元素(如“i
”或“b
”或“list
”分组到“p
”元素中.确保 div
不应该成为 p
.
XML:(带有换行符或空格以供显示,运行 在第 2 个 XML 下方使用)
<article>
<body>
<para>
<display><fig>Fig1</fig></display>
the text node1
</para>
<para>
<display><fig>Fig1</fig></display>
</para>
<para>
<display><fig>Fig1</fig></display>
the text node1 <i>h</i> ther <b>b</b> the text4
<display><tab>Table1</tab></display>
the text node2
<list><li>list1</li></list>
</para>
<para>The text node3</para>
</body>
</article>
XML:(没有换行符)
<article><body><para><display><fig>Fig1</fig></display>the text node1</para><para><display><fig>Fig1</fig></display></para><para><display><fig>Fig1</fig></display>the text node1 <i>h</i> ther <b>b</b> the text4<display><tab>Table1</tab></display>the text node2<list><li>list1</li></list></para><para>The text node3</para></body></article>
XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
<xsl:template match="para">
<xsl:choose>
<xsl:when test="not(text())"><xsl:apply-templates/></xsl:when>
<xsl:when test="display and text() or *">
<xsl:for-each select="node()">
<xsl:choose>
<xsl:when test="name()='display'"><div><xsl:apply-templates/></div></xsl:when>
<xsl:when test="name()='i' or name()='b'">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:when>
<xsl:when test="not(*)"><p><xsl:value-of select="."/></p></xsl:when><!--Here grouping required with adjacent elements 'i' or 'b' etc -->
<xsl:otherwise><p><xsl:apply-templates/></p></xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<p><xsl:apply-templates/></p>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
所需结果:
<article>
<body>
<div><fig>Fig1</fig></div><!--ensure div should not child to 'p'-->
<p>the text node1</p> <!--Text area including 'i' and 'b' to be within 'p' -->
<div><fig>Fig1</fig></div>
<div><fig>Fig1</fig></div>
<p>the text node1 <i>h</i> ther <b>b</b> the text4</p><!--Text area including 'i' and 'b' to be within 'p' -->
<div><tab>Table1</tab></div>
<p>the text node2<list><li>list1</li></list></p><!--text area includes 'list' element -->
<p>The text node3</p>
</body>
</article>
当您使用 XSLT 2.0 时,您可以在此处使用 xsl:for-each-group
,根据相邻子节点是否为 display
元素对它们进行分组。
<xsl:for-each-group select="node()" group-adjacent="boolean(self::display)">
因此,除 display
之外的节点将具有 false
的分组键,因此被分组在一起,允许您将它们包装在 p
标签中
试试这个 XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
</xsl:template>
<xsl:template match="para">
<xsl:for-each-group select="node()" group-adjacent="boolean(self::display)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:apply-templates select="current-group()" />
</xsl:when>
<xsl:otherwise>
<p>
<xsl:apply-templates select="current-group()" />
</p>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="display">
<div>
<xsl:apply-templates />
</div>
</xsl:template>
</xsl:stylesheet>
我想你可以使用 for-each-group group-adjacent="boolean(self::text() | self::i |.."
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="para">
<xsl:for-each-group select="node()" group-adjacent="boolean(self::text() | self::i | self::b | self::list)">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<p>
<xsl:apply-templates select="current-group()"/>
</p>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="display">
<div>
<xsl:apply-templates/>
</div>
</xsl:template>
</xsl:stylesheet>