XSL使用元素名称中的字符实体转换xml

时间:2019-02-04 02:30:51

标签: xml xslt character-entities

我的xml如下:

<record>
    <name>ABC</name>
    <address>
        &lt;street&gt;sss&lt;/street&gt;
        &lt;city&gt;ccc&lt;/city&gt;
        &lt;state&gt;ttt&lt;/state&gt;
    </address>
</record>

我正在尝试使用xsl读取元素“ street”:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output omit-xml-declaration="yes" indent="yes" />
    <xsl:template match="/">
        <xsl:value-of select="record/address/street" />
    </xsl:template>
</xsl:stylesheet>

但没有任何输出。

即使输入xml为有效xml格式,为什么仍会发生这种情况? 那么如何转换包含元素名称的字符实体的xml文件呢?

3 个答案:

答案 0 :(得分:0)

没有street元素。如果将其写为<street>...</street>,那么它将是一个元素,但是尖括号已被小心地转义以表示应将其视为纯文本。

将包含尖括号的纯文本转换为XML节点结构涉及解析;也就是说,您需要对address元素的文本内容执行第二次解析。事实很复杂,因为这里的内容是XML片段而不是完整的XML文档。

在XSLT 3.0中,您可以使用parse-xml-fragment()函数实现此目的。在早期版本中,您可以通过调用自定义扩展功能或(如@sandeepkamboj所建议的)通过在XSLT中编写一个简单的XML解析器来实现(为此,您需要确信知道XML的哪个子集)您需要处理的结构)。

也许最好的方法是找出为什么有人生成了这个荒谬的文档,并使他们改正自己的方式。

答案 1 :(得分:0)

要添加到Michael Kay的答案中:

如果您首先使用以下方法处理XML:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

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

</xsl:stylesheet>

并将结果保存到文件中,然后您便可以使用样式表来处理生成的文件并获得预期的结果。

答案 2 :(得分:-2)

    <xsl:template match="//name"/>
<xsl:template match="record/address">
    <xsl:value-of select="substring-before(., '&lt;city&gt;ccc&lt;/city&gt;')" disable-output-escaping="yes"/>
</xsl:template>

检查此代码。