在XML转换中两次取消引用HTML实体

时间:2015-06-03 09:30:35

标签: xslt

我尝试将Jiira票证XML导出转换为带有XML转换的文本。 XML代码包含带引号的HTML实体和元素的注释元素。

元素

例如,在XML导出中将新行写为。

<br/>

当我使用以下XSL代码输出时:

<xsl:value-of select="." disable-output-escaping="yes"/>

我得到了HTML元素:

<br>

但我需要输出一个新行。

所以我尝试了这个:

<xsl:value-of select="replace(., '&lt;br/&gt;', '&#xa;')" disable-output-escaping="yes"/>

这是有效的,但仅适用于&#39; br&#39;元件。

实体

这同样适用于实体。用这种方式引用箭头:

--&amp;gt;

使用disable-output-escaping,我得到了这个:

--&gt;

但我需要这个:

-->

这意味着我必须两次取消引用。如何在XSLT中完成?

2 个答案:

答案 0 :(得分:0)

您不能在普通的XSLT中(除非您在XSLT中实现HTML解析器)。您必须1)预处理输入以将词法HTML转换为XML元素,2)对输出进行后处理,或3)使用扩展函数从XSLT中解析HTML。

答案 1 :(得分:0)

你可以逃脱

<xsl:preserve-space elements="*" />

如果源内容已经包含您想要的空格。

如果你想修改它,它会变得有点棘手。

如果您只有XSL 1.0,那么最好的方法就是应用两个转换,一个转换为unescape,另一个转换为白色空间处理。

如果您有XSL 2.0,那么您可能拥有Saxon,这意味着您可以使用parse等扩展功能。

Parse允许您将字符串内容评估为节点结果,然后可以将其传递给模板处理。例如,拿这个xml

<?xml version="1.0" encoding="UTF-8"?>
    <example>
    <content>&lt;br&gt;
        This &lt;i&gt;is&lt;/i&gt; html
        &lt;/br&gt;
    </content>
</example>

这个样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:saxon="http://saxon.sf.net/">
    <xsl:template match="/">
        <output>
            <xsl:variable name="PREPROCESSED" select="saxon:parse(/example/content)"/>
            <xsl:apply-templates select="$PREPROCESSED" mode="postprocess"/>
        </output>
    </xsl:template>
    <xsl:template match="@*|node()" mode="postprocess">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" mode="postprocess"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="i" mode="postprocess">
        <b><xsl:apply-templates select="."/></b>
    </xsl:template>
</xsl:stylesheet>

将屈服:

<?xml version="1.0" encoding="UTF-8"?><output xmlns:saxon="http://saxon.sf.net/"><br>
        This <b>is</b> html
        </br></output>