分析 text() 节点并在 XSLT 中添加新节点
Analyze text() node and add new nodes in XSLT
我正在使用 XSLT 进行 html 到 xml 的转换,在 html 输入中我有如下内容,
<p>An image outside a paragraph is placed into an <em>Element Image Frame</em>. If there are no (or not enough) <em>Element Image Frames</em> then the image is ignored and a warning is logged.</p>
使用xsl,我需要的是,如果在<em>
节点之前或之后有space,那些节点应该被替换为,<space/>
节点。所以预期的输出,
<p>An image outside a paragraph is placed into an<space/><Italic>Element Image Frame</Italic>. If there are no (or not enough)<space/><Italic>Element Image Frames</Italic><space/>then the image is ignored and a warning is logged.</p>
注意第一个<em>
节点后没有space,所以没有添加<space/>
我想我可以使用 XSLT 正则表达式,但我很难用 select 在 <em>
节点前后两个 space 编写一个正则表达式。
<xsl:template match="p/text()">
<xsl:analyze-string select="." regex="^( )">
<xsl:matching-substring>
<xsl:choose>
<xsl:when test="regex-group(1)">
<space/>
</xsl:when>
</xsl:choose>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
任何人都可以建议我一个方法来做到这一点..
whitespaces 的正确选择器是 ([\s\t]+)$
,它表示末尾至少有一个 whitespace(space 或制表符)应该匹配并且可以然后被替换。不过,我没有资源用您的特定代码对其进行测试。
由于可以使用 starts-with
and/or ends-with
检查条件,但还涉及某个同级元素的存在,我会简单地编写具有匹配模式的模板:
<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()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="em">
<Italics>
<xsl:apply-templates select="@* | node()"/>
</Italics>
</xsl:template>
<xsl:template match="p/text()[starts-with(., ' ') and preceding-sibling::node()[1][self::em]]">
<space/>
<xsl:value-of select="substring(., 2)"/>
</xsl:template>
<xsl:template match="p/text()[ends-with(., ' ') and following-sibling::node()[1][self::em]]">
<xsl:value-of select="substring(., 1, string-length() - 1)"/>
<space/>
</xsl:template>
<xsl:template match="p/text()[starts-with(., ' ') and preceding-sibling::node()[1][self::em] and
ends-with(., ' ') and following-sibling::node()[1][self::em]]" priority="5">
<space/>
<xsl:value-of select="substring(., 2, string-length() - 1)"/>
<space/>
</xsl:template>
</xsl:stylesheet>
我正在使用 XSLT 进行 html 到 xml 的转换,在 html 输入中我有如下内容,
<p>An image outside a paragraph is placed into an <em>Element Image Frame</em>. If there are no (or not enough) <em>Element Image Frames</em> then the image is ignored and a warning is logged.</p>
使用xsl,我需要的是,如果在<em>
节点之前或之后有space,那些节点应该被替换为,<space/>
节点。所以预期的输出,
<p>An image outside a paragraph is placed into an<space/><Italic>Element Image Frame</Italic>. If there are no (or not enough)<space/><Italic>Element Image Frames</Italic><space/>then the image is ignored and a warning is logged.</p>
注意第一个<em>
节点后没有space,所以没有添加<space/>
我想我可以使用 XSLT 正则表达式,但我很难用 select 在 <em>
节点前后两个 space 编写一个正则表达式。
<xsl:template match="p/text()">
<xsl:analyze-string select="." regex="^( )">
<xsl:matching-substring>
<xsl:choose>
<xsl:when test="regex-group(1)">
<space/>
</xsl:when>
</xsl:choose>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
任何人都可以建议我一个方法来做到这一点..
whitespaces 的正确选择器是 ([\s\t]+)$
,它表示末尾至少有一个 whitespace(space 或制表符)应该匹配并且可以然后被替换。不过,我没有资源用您的特定代码对其进行测试。
由于可以使用 starts-with
and/or ends-with
检查条件,但还涉及某个同级元素的存在,我会简单地编写具有匹配模式的模板:
<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()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="em">
<Italics>
<xsl:apply-templates select="@* | node()"/>
</Italics>
</xsl:template>
<xsl:template match="p/text()[starts-with(., ' ') and preceding-sibling::node()[1][self::em]]">
<space/>
<xsl:value-of select="substring(., 2)"/>
</xsl:template>
<xsl:template match="p/text()[ends-with(., ' ') and following-sibling::node()[1][self::em]]">
<xsl:value-of select="substring(., 1, string-length() - 1)"/>
<space/>
</xsl:template>
<xsl:template match="p/text()[starts-with(., ' ') and preceding-sibling::node()[1][self::em] and
ends-with(., ' ') and following-sibling::node()[1][self::em]]" priority="5">
<space/>
<xsl:value-of select="substring(., 2, string-length() - 1)"/>
<space/>
</xsl:template>
</xsl:stylesheet>