这个问题与我发布的另一个问题有关,并且仍在尝试解决:XML - XSLT - Using two XML files - Additions to XML file consulting another XML file,但是由于这是一个简单的问题,因此我决定为此撰写新的帖子,以解决这个问题。
对于以后的读者来说,更多的“可读性”和有用之处我有以下XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<entry>
<text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]></text-prop>
</entry>
我正在使用XSLT执行简单的身份转换方法:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
但是我得到了输出:
<?xml version="1.0" encoding="utf-8"?>
<entry>
<text-prop name="content"><value-of>new Date()</value-of></text-prop>
</entry>
但是我希望输出XML与输入XML完全一样
<?xml version="1.0" encoding="UTF-8"?>
<entry>
<text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]> </text-prop>
</entry>
是否有一种简单的方法可以这样做,并且可能会转义XML中所有可能的特殊字符?
我正在使用Saxon 9.8,所以我可以使用我认为是3.0的最新版本的XSLT,
谢谢!
Alexandre Jacinto
编辑
我设法像这样使用cdata-section-elements
来转义字符:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="utf-8" cdata-section-elements="text-prop"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
但是当我尝试使用不同的输入时,我在之前引用的帖子中使用的输入是:
<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23" id="1">
<text-prop name="displayName">PersonTemplate</text-prop>
<setup>
<simple-master-page name="MasterPage" id="2">
<footer>
<text id="3">
<prop name="contentType">html</prop>
<text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]></text-prop>
</text>
</footer>
</simple-master-page>
</setup>
<body>
<table id="4">
<column id="17"/>
<column id="18"/>
<column id="19"/>
<header>
<row id="5">
<cell id="6">
<label id="20">
<text-prop name="text">NameTitle</text-prop>
</label>
</cell>
<cell id="7">
<label id="21">
<text-prop name="text">CityTitle</text-prop>
</label>
</cell>
<cell id="8">
<label id="22">
<text-prop name="text">AgeTitle</text-prop>
</label>
</cell>
</row>
</header>
<detail>
<row id="9">
<cell id="10"/>
<cell id="11"/>
<cell id="12"/>
</row>
</detail>
</table>
</body>
</report>
转义不起作用,所以我得到了:
<?xml version="1.0" encoding="utf-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23" id="1">
<text-prop name="displayName">PersonTemplate</text-prop>
<setup>
<simple-master-page name="MasterPage" id="2">
<footer>
<text id="3">
<prop name="contentType">html</prop>
<text-prop name="content"><value-of>new Date()</value-of></text-prop>
</text>
</footer>
</simple-master-page>
</setup>
<body>
<table id="4">
<column id="17"/>
<column id="18"/>
<column id="19"/>
<header>
<row id="5">
<cell id="6">
<label id="20">
<text-prop name="text">NameTitle</text-prop>
</label>
</cell>
<cell id="7">
<label id="21">
<text-prop name="text">CityTitle</text-prop>
</label>
</cell>
<cell id="8">
<label id="22">
<text-prop name="text">AgeTitle</text-prop>
</label>
</cell>
</row>
</header>
<detail>
<row id="9">
<cell id="10"/>
<cell id="11"/>
<cell id="12"/>
</row>
</detail>
</table>
</body>
</report>
例如,您可以看到<
字符继续打印为<
,
我只是不明白为什么它适用于第一个和更简单的输入XML,但不适用于第二个和更简单的输入
我该如何解决?
谢谢!
编辑
我应用了此XSLT代码:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xmlbirtns="http://www.eclipse.org/birt/2005/design">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes" encoding="utf-8" cdata-section-elements="xmlbirtns:text-prop"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在XSLT文件中声明输入XML使用的名称空间
我正确地使用了<CDATA>
,但是现在,因为我有更多的<text-prop>
元素,所以每个<CDATA>
元素中的输出都带有<text-prop>
标签,就像这样:
<?xml version="1.0" encoding="utf-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design" version="3.2.23" id="1">
<text-prop name="displayName"><![CDATA[PersonTemplate]]></text-prop>
<setup>
<simple-master-page name="MasterPage" id="2">
<footer>
<text id="3">
<prop name="contentType">html</prop>
<text-prop name="content"><![CDATA[<value-of>new Date()</value-of>]]></text-prop>
</text>
</footer>
</simple-master-page>
</setup>
<body>
<table id="4">
<column id="17"/>
<column id="18"/>
<column id="19"/>
<header>
<row id="5">
<cell id="6">
<label id="20">
<text-prop name="text"><![CDATA[NameTitle]]></text-prop>
</label>
</cell>
<cell id="7">
<label id="21">
<text-prop name="text"><![CDATA[CityTitle]]></text-prop>
</label>
</cell>
<cell id="8">
<label id="22">
<text-prop name="text"><![CDATA[AgeTitle]]></text-prop>
</label>
</cell>
</row>
</header>
<detail>
<row id="9">
<cell id="10"/>
<cell id="11"/>
<cell id="12"/>
</row>
</detail>
</table>
</body>
</report>
安装了我想要的输出XML,与输入XML完全一样
我知道我可能无法使用cdata-section-elements
的{{1}}属性。
注意::在我的输入XML中,我只有一个xsl:output
元素,其中包含值,其他所有元素都具有普通文本。
答案 0 :(得分:0)
由于XSLT始终首先匹配最准确的模板,因此您可以匹配setup / text-prop并专门为此部分创建一个CDATA块。 然后根据XML,可以使用apply-templates继续匹配其他元素。
它可能看起来像这样:
<xsl:template match="setup/text-prop">
<xsl:copy>
<setup>
<text-prop>
<xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:value-of>whatever</xsl:value-of>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</text-prop>
</setup>
<xsl:copy>
<xsl:apply-templates/>
</xsl:template>
答案 1 :(得分:0)
首先,CDATA不是XDM数据模型的一部分,它被认为是转义特殊字符的两种方式:
<X><![CDATA[<>]]></X>
和
<X><></X>
被认为是完全可以互换的。
这意味着您的样式表无法区分输入中使用了这两种样式:无法知道。
xsl:output的cdata-section-elements属性使您可以控制在输出中使用哪种形式,但是正如您所发现的那样,它不能完全控制您。
您可以通过使用禁用输出转义,字符映射或Andrew Welch的lexev实用程序来获得更多控制,但是所有这些变通办法都引出了一个问题,为什么它如此重要?如果某人根据是否使用CDATA对结果文档进行不同的处理,那么他们正在滥用XML,需要对其进行重新培训。