如何通过XSLT复制CDATA内<xml>标签并保留CDATA格式添加节点
解决方案:用XSLT复制CDATA内的标签并添加节点,保持CDATA格式
我来帮你搞定这个XSLT处理CDATA的问题——这确实是个容易踩坑的点,尤其是要同时完成复制原有XML内容、添加新节点还得保留CDATA格式。下面是完整的实现思路和代码:
1. 先明确文件结构假设
先假设你的源文件(比如叫source.xml)结构大概是这样的(如果实际结构不同,调整XPath路径就行):
<SourceRoot> <CdataContent><![CDATA[<xml> <!-- 这里是你要复制的原有XML内容 --> <existingNode>原始内容</existingNode> </xml>]]></CdataContent> </SourceRoot>
你要添加的新内容就是这段:
<Data> <RawData Format="Text"> <organizationNameEng>fgfgfg</organizationNameEng> <organizationNameGeo>dfdfdf</organizationNameGeo> <organizationIdentifier>123456789</organizationIdentifier> <!-- 省略的其他节点 --> </RawData> </Data>
2. XSLT 2.0+实现代码
下面的XSLT会完成:解析原CDATA里的shablon.xml:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 配置输出:指定要包裹CDATA的元素 --> <xsl:output method="xml" indent="yes" cdata-section-elements="FinalContent"/> <!-- 定义要添加的新节点,也可以改成从外部文件读取 --> <xsl:variable name="newData"> <Data> <RawData Format="Text"> <organizationNameEng>fgfgfg</organizationNameEng> <organizationNameGeo>dfdfdf</organizationNameGeo> <organizationIdentifier>123456789</organizationIdentifier> <!-- 补充你剩下的节点 --> </RawData> </Data> </xsl:variable> <xsl:template match="/"> <!-- 生成shablon.xml的根结构 --> <shablonRoot> <FinalContent> <!-- 第一步:把原CDATA的文本解析成XML节点树 --> <xsl:variable name="originalXmlTree" select="parse-xml(SourceRoot/CdataContent/text())"/> <!-- 第二步:复制原<xml>里的所有内容 --> <xsl:copy-of select="$originalXmlTree/xml/*"/> <!-- 第三步:插入新的<Data>节点 --> <xsl:copy-of select="$newData/Data"/> </FinalContent> </shablonRoot> </xsl:template> </xsl:stylesheet>
3. 代码关键逻辑解释
parse-xml()函数:把CDATA里的纯文本转成可操作的XML节点树,这是XSLT 2.0及以上版本支持的功能,比1.0的扩展函数好用太多,建议用Saxon这类支持2.0+的处理器。cdata-section-elements="FinalContent":告诉XSLT处理器,把FinalContent元素里的所有内容自动包裹成CDATA输出,完美保留格式。- 如果新节点内容存在外部文件里,把
newData变量改成<xsl:variable name="newData" select="document('你的新内容文件路径.xml')"/>就行。
4. 最终输出效果
执行后shablon.xml的内容会是这样的:
<?xml version="1.0" encoding="UTF-8"?> <shablonRoot> <FinalContent><![CDATA[<existingNode>原始内容</existingNode> <Data> <RawData Format="Text"> <organizationNameEng>fgfgfg</organizationNameEng> <organizationNameGeo>dfdfdf</organizationNameGeo> <organizationIdentifier>123456789</organizationIdentifier> <!-- 其他节点 --> </RawData> </Data>]]></FinalContent> </shablonRoot>
小提示
如果只能用XSLT 1.0,那得借助扩展函数(比如exsl:node-set())来处理字符串转节点,但操作会麻烦不少,优先推荐用2.0+的处理器。另外要确保原CDATA里的
内容的提问来源于stack exchange,提问作者beginer beginer
相关产品推荐
相关产品推荐

