XSLT 2.0处理无效节点混合文本和CDATA
我需要解析以下节点:XSLT 2.0处理无效节点混合文本和CDATA
<media:keywords>keyword1,keyword2<![CDATA[keyword3]]></media:keywords>
成有效的串,优选“关键字1,关键字2,KEYWORD3”,但我会满足于完全除去CDATA。
试图访问该节点给我的文字“keyword1,keyword2keyword3”,我不能告诉CDATA开始的地方。
原始的XML(简化mRSS资讯版)
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/">
<channel>
<item>
<media:keywords>keyword1,keyword2<![CDATA[keyword3]]></media:keywords>
</item>
</channel>
</rss>
XSL(简体):
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:media="http://search.yahoo.com/mrss/" exclude-result-prefixes="xs xsi fn">
<xsl:output method="xml" encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:template match="/">
<test>
<xsl:variable name="items" select="/rss/channel/item"/>
<xsl:for-each select="$items">
<xsl:variable name="mediakw" select="media:keywords"/>
<xsl:element name="mediaKeyWords">
<xsl:value-of select="$mediakw"/>
</xsl:element>
</xsl:for-each>
</test>
</xsl:template>
</xsl:stylesheet>
和输出:
<test xmlns:media="http://search.yahoo.com/mrss/"><mediaKeyWords>keyword1,keyword2keyword3</mediaKeyWords></test>
非常感谢!
XML和XSLT不能帮你在这里。
XSLT使用INFOSET模型,其中有没有什么作为 “CDATA节点”和存在的仅仅是单个文本()节点:
“关键字,keyword2keyword3”
的XML文档需要校正和逗号的子串"keyword2"
和"keyword3"
一种解决方案之间插入将处理CDATA DOM节点使用DOM,然后才启动XSLT转换。
另外XDM也是如此。 – 2010-11-16 17:49:16
+1好点。我不知道DOM提供CDATASection作为可选的“扩展接口”。我想知道哪些处理器支持。 – LarsH 2010-11-16 19:28:34
@LarsH:MSXML和.NET XmlReader(NodeTypeEnumeration) – 2010-11-16 19:36:54
当XSLT处理器看到文本时,CDATA消失了。您无法看到传入的CDATA,并且几乎无法控制如何生成输出CDATA(对于给定标记全部或全部没有)。
无法在标准XSLT中完成。
输入XML您收到,
<media:keywords>keyword1,keyword2<![CDATA[keyword3]]></media:keywords>
是没有区别(以XSLT)从
<media:keywords>keyword1,keyword2keyword3</media:keywords>
因为CDATA标记是逃避它里面的数据的只是一种方法。在这种情况下,确实没有特别的标记可以逃脱,所以CDATA恰好是没有操作的。但是XSLT无法知道最初使用CDATA表达了什么数据,使用字符实体表达了什么等等。
解决方法是告诉谁提供这个XML,他们需要在关键字2和关键字3之间加上一个分隔符。
@LarsH:不仅可以区分为XSLT,还可以按照@ Dimitre指出的Infoset规范或现代XDM,为每个XML树提供程序区分开来。 – 2010-11-16 17:48:04
@Alejandro:对(虽然XML语言/工具规范*可以*使用有关CDATA部分的信息,而不会实际违反Infoset规范......请参阅http://www.w3.org/TR/xml-infoset/#conformance,第3项)。我指定了XSLT,因为OP询问了一个XSLT解决方案。 – LarsH 2010-11-16 18:05:06
@LarsH:是的,一个实现可以扩展Infoset,但标准**明确**在http://www.w3.org/TR/xml-infoset/#omitted中说:*以下信息未在当前版本的XML信息集:19. CDATA标记的区域的边界* – 2010-11-16 18:13:48
如果您分别使用Saxon和XSLT 2.0处理器的Java实现,请查看将http://andrewjwelch.com/lexev/插入到处理链中,这样可以将CDATA部分更改为标记,然后XSLT处理器可以操作。 – 2010-11-16 17:54:24