使用cdata转义XML,该cdata还具有转义的数据值和标记
本文关键字:cdata 转义 数据 XML 使用 | 更新日期: 2023-09-27 18:18:19
我正在从一个web服务接收xml数据,该服务将所有数据作为一个转义的xml字符串返回。但是,由于某种原因,XML的一部分被包含在cdata标记中。cdata中的转义xml通常也包含转义xml字符。例子:
<root>
<importData>dat</importData>
<Response>
<![CDATA[<SecondRoot>
<Data>123</Data>
<DataEscapedCharacterIncluded> 3 > 1</DataEscapedCharacterIncluded>
</SecondRoot>]]>
</Response>
</root>
我需要用xsl将cdata部分内部和外部的xml转换为另一种xml格式,但是我很难弄清楚如何使用c#或xsl将其转换为可用的xml形式,因此我可以将xsl转换为不同的格式。我希望它看起来像这样:
<root>
<importData>dat</importData>
<Response>
<SecondRoot>
<Data>123</Data>
<DataEscapedCharacterIncluded> 3 > 1</DataEscapedCharacterIncluded>
</SecondRoot>
</Response>
<root>
显示的数据可能没有正确转义。如果对其进行反转义,则可能产生格式不佳的XML。考虑这一行:
<DataEscapedCharacterIncluded> 3 > 1</DataEscapedCharacterIncluded>
如果你取消转义,它将变成这样:
<DataEscapedCharacterIncluded> 3 > 1</DataEscapedCharacterIncluded>
这仍然是有效的(大于不需要转义),但我假设您还会在那里的某个地方有<
,其中必须转义。如果它是双重转义的,应该没问题。
要转换它,你可以做几件事:
- 使用XSLT 1.0或2.0,分两步对其进行转换,其中一步完成不转义,将
disable-output-escaping
设置为yes
,另一个一个来做实际的转换。 - 使用一个扩展函数,该函数接受一个字符串并返回一个节点集。
- 在XSLT 3.0中,使用新的函数
fn:parse-xml
或fn:parse-xml-fragment
,它可以将xml作为字符串作为输入。 - 如果您的整个源被转义,就像它看起来的那样,将未转义的源馈送到XSLT处理器。这也会照顾到转义后的CDATA(但该部分仍将转义,见下文)。
从你的帖子中不完全清楚的是它是否被双重转义。例如,如果您的数据看起来像这样:
<elem><![CDATA[<root>bla</root>]]></elem>
被单独转义。如果它看起来像这样:
<elem><![CDATA[<root>bla</root>]]></elem>
被双重转义。在后一种情况下,您需要在处理它之前执行一个额外的unescape循环。