以下是具有CDATA部分的 对于上面的xml我需要撕掉CDATA并在现有元素“film”下添加新元素,所以最终的输出将是: 这可以使用XSLT完成吗? <?xml version="1.0" encoding="ISO-8859-1"?>
<character>
<name>
<role>Indiana Jones</role>
<actor>Harrison Ford</actor>
<part>protagonist</part>
<![CDATA[ <film>Indiana Jones and the Kingdom of the Crystal Skull</film>]]>
</name>
</character>
<?xml version="1.0" encoding="ISO-8859-1"?>
<character>
<name>
<role>Indiana Jones</role>
<actor>Harrison Ford</actor>
<part>protagonist</part>
<film>Indiana Jones and the Kingdom of the Crystal Skull</film>
<Language>English</Language>
</name>
</character>
答案 0 :(得分:3)
略微修改的识别功能应该有效。
鉴于此XML:
<?xml version="1.0" encoding="ISO-8859-1"?>
<character>
<name>
<role>Indiana Jones</role>
<actor>Harrison Ford</actor>
<part>protagonist</part>
<![CDATA[ <film>Indiana Jones and the Kingdom of the Crystal Skull</film>]]>
</name>
</character>
使用此XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="*" />
<xsl:value-of select="text()" disable-output-escaping="yes"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
会产生此输出:
<?xml version="1.0" encoding="UTF-8"?>
<character>
<name>
<role>Indiana Jones</role>
<actor>Harrison Ford</actor>
<part>protagonist</part>
<film>Indiana Jones and the Kingdom of the Crystal Skull</film>
</name>
</character>
(使用Saxon-HE 9.3.0.5在oXygen 12.2中测试。)
答案 1 :(得分:2)
由于CDATA块中的film
元素似乎格式正确,因此可以使用disable-output-escaping。如果匹配名称/文本(),请选择带有DOE的value-of,然后立即插入Language
元素。
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" />
<!--Identity template simply copies content forward -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="name/text()">
<!--disable-output-escaping will prevent the "film" element from being escaped.
Since it appears to be well-formed you should be safe, but no guarentees -->
<xsl:value-of select="." disable-output-escaping="yes" />
<Language>English</Language>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:1)
解决此问题的另一种方法是使用Andrew Welsh LexEv XMLReader来进一步控制转换。这使您可以将CDATA部分作为标记处理。
答案 3 :(得分:0)
首先,您的输入XML具有“CDATA”的事实在某种意义上是无关紧要的...... XSLT无法判断它是否是CDATA。您的输入XML的关键在于您已转义标记<film>...</film>
,并且您希望将其转换为真实元素。
如果您知道转义元素将始终具有特定名称(“电影”),并且您知道它发生的位置,则可以将其剥离并轻松替换:
<xsl:template match="text()[contains(., '<film>')]">
<film>
<xsl:value-of select="substring-before(substring-after(., '<film>'),
'</film>')"/>
</film>
</xsl:template>
如果您事先不知道转发标记的位置以及元素名称,您可以使用XSLT 2.0的<xsl:analyze-string>
来查找和替换它们。但正如Alejandro指出的那样,使用正则表达式对XML进行一般解析会变得非常混乱。只有你知道标记很简单才有可能。
答案 4 :(得分:0)
我正在处理类似的事情,我找到了一个很好的解决方案,所以我想与你分享,但这个是NSXMLParser
。
如果您使用NSXMLParser
,则会有一个名为foundCDATA
的委托方法,如下所示:
- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock{
if (!parseElement) {
return;
}
if (parsedElementData==nil) {
parsedElementData = [[NSMutableData alloc] init];
}
[parsedElementData appendData:CDATABlock];
//Grabs the whole content in CDATABlock.
NSMutableString *content = [[NSMutableString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding];
}
现在将this prewritten class添加到您的项目中。然后将其导入要在其中使用的解析器类:
#import NSString_stripHTML
现在,您可以将以下行添加到foundCDATA
方法:
NSString *strippedContent;
strippedContent = [content strippedHtml];
现在您将删除没有任何额外字符的剥离文本。你可以从这个剥离的文本中对你想要的任何内容进行子串。