分析text()节点并在XSLT中添加新节点

时间:2015-11-19 09:36:27

标签: xml xslt xslt-2.0

我正在使用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/>节点替换。所以预期的产出,

<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/>

我想我可以使用XSLT正则表达式,但是我很难在<em>节点前后选择两个空格来编写正则表达式。

<xsl:template match="p/text()">
        <xsl:analyze-string select="." regex="^(&#x20;)">
            <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>

任何人都可以建议我这样做的方法..

2 个答案:

答案 0 :(得分:2)

由于条件可以使用starts-with和/或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>

答案 1 :(得分:0)

正确的空格选择器是([\s\t]+)$,它表示最后应该匹配至少一个空格(空格或制表符),然后可以替换它们。但是我没有资源用你的特定代码测试它。