包含文本和子节点的 XSLT 拆分元素
XSLT split element containing text and child nodes
我有一个包含文本和子元素的节点。我想将每个句子分成不同的元素。问题是该元素可以有子节点,甚至可以有带有分隔符(句号)的孙子节点。
所以这个 XML:
<text>
<p>Lorem ipsum dolor sit <a>amet</a>, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis <b>aute</b> irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat <d>non <c>proident</c>, sunt in. culpa</d> qui officia deserunt mollit anim id est laborum.</p>
</text>
应该在 current() 元素中用句点分隔(但不在子元素中,例如,参见元素 <d/>
中的句点)。
期望的输出:
<text>
<sentence>Lorem ipsum dolor sit <a>amet</a>, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.</sentence>
<sentence>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
ea commodo consequat.</sentence>
<sentence>Duis <b>aute</b> irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.</sentence>
<sentence>Excepteur sint occaecat cupidatat <d>non <c>proident</c>, sunt in.
culpa</d> qui officia deserunt mollit anim id est laborum.</sentence>
</text>
我看过这个答案: 和 <xsl:for-each-group select="node()" group-adjacent="boolean(self::separator)"> or group-starting-with="separator"
但到目前为止,它并没有帮助我选择 text/nodes 领先的时期。
我可以使用 XSLT 2/3。
通过使用一种模式将 p
的文本子项中的点转换为元素,然后使用 group-ending-with
进行分组步骤,这应该很容易:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="p">
<xsl:variable name="marked-text" as="node()*">
<xsl:apply-templates mode="insert-marker"/>
</xsl:variable>
<xsl:for-each-group select="$marked-text" group-ending-with="full-stop">
<sentence>
<xsl:apply-templates select="current-group()"/>
</sentence>
</xsl:for-each-group>
</xsl:template>
<xsl:mode name="insert-marker" on-no-match="shallow-copy"/>
<xsl:template mode="insert-marker" match="p/text()">
<xsl:analyze-string select="." regex="\.">
<xsl:matching-substring>
<full-stop>.</full-stop>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template match="full-stop">
<xsl:text>.</xsl:text>
</xsl:template>
</xsl:stylesheet>
我有一个包含文本和子元素的节点。我想将每个句子分成不同的元素。问题是该元素可以有子节点,甚至可以有带有分隔符(句号)的孙子节点。
所以这个 XML:
<text>
<p>Lorem ipsum dolor sit <a>amet</a>, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
laboris nisi ut aliquip ex ea commodo consequat. Duis <b>aute</b> irure dolor in reprehenderit in
voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat <d>non <c>proident</c>, sunt in. culpa</d> qui officia deserunt mollit anim id est laborum.</p>
</text>
应该在 current() 元素中用句点分隔(但不在子元素中,例如,参见元素 <d/>
中的句点)。
期望的输出:
<text>
<sentence>Lorem ipsum dolor sit <a>amet</a>, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.</sentence>
<sentence>Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex
ea commodo consequat.</sentence>
<sentence>Duis <b>aute</b> irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.</sentence>
<sentence>Excepteur sint occaecat cupidatat <d>non <c>proident</c>, sunt in.
culpa</d> qui officia deserunt mollit anim id est laborum.</sentence>
</text>
我看过这个答案:<xsl:for-each-group select="node()" group-adjacent="boolean(self::separator)"> or group-starting-with="separator"
但到目前为止,它并没有帮助我选择 text/nodes 领先的时期。
我可以使用 XSLT 2/3。
通过使用一种模式将 p
的文本子项中的点转换为元素,然后使用 group-ending-with
进行分组步骤,这应该很容易:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="p">
<xsl:variable name="marked-text" as="node()*">
<xsl:apply-templates mode="insert-marker"/>
</xsl:variable>
<xsl:for-each-group select="$marked-text" group-ending-with="full-stop">
<sentence>
<xsl:apply-templates select="current-group()"/>
</sentence>
</xsl:for-each-group>
</xsl:template>
<xsl:mode name="insert-marker" on-no-match="shallow-copy"/>
<xsl:template mode="insert-marker" match="p/text()">
<xsl:analyze-string select="." regex="\.">
<xsl:matching-substring>
<full-stop>.</full-stop>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template match="full-stop">
<xsl:text>.</xsl:text>
</xsl:template>
</xsl:stylesheet>