java cdata类,分析XML中的CDATA类型在RSS中的使用

除经特别注明外,本站文章版权归JScud Develop团队或其原作者所有.

转载请注明作者和来源.  scud(飞云小侠)    欢迎访问 JScud Develop

根据XML中CDATA类型的规范可以知道:"&"和"" 如果出现在"]]>" 的内容而不是表示结束时,必须被转义为>

但是这样就存在一个问题,如果我需要输入"]]>",正确的处理是保存为"]]>",但是如果我想输入"]]>",那么应该如何保存哪? 我想了很久,除非加空格或者采用特殊的办法,否则是没有办法解决的.

1.如果我们不考虑输入"]]>"的问题,来考虑一下"]]>"的处理,看看各种XML解析器是如何处理的?

xml解析器的测试包含2个部分:设置cdata类型的数据和读出cdata类型的数据.

首先我们写一个测试的例子,计划使用JDom 1.0和Dom4j来测试一下:

package com.jscud.test;

public class XmlTestBase

{

public static String xmlpart =

"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+

"" +

""+

"" +

"" +

"";

public static void print(String str)

{

System.out.println(str);

}

}

JDom测试的例子如下:

package com.jscud.test;

import java.io.*;

import org.jdom.*;

import org.jdom.input.SAXBuilder;

import org.jdom.output.*;

//@author scud http://www.jscud.com

public class JDomXmlFileTest extends XmlTestBase

{

public static void main(String[] args) throws Exception

{

readDocument();

print("===========================");

createDocument();

}

public static void readDocument() throws Exception

{

Reader reader = new StringReader(xmlpart);

SAXBuilder builder = new SAXBuilder();

Document doc = builder.build(reader);

Element aRoot = doc.getRootElement();

Element anode = aRoot.getChild("test").getChild("hello");

print(anode.getText());

}

public static void createDocument() throws Exception

{

Document doc = new Document();

doc.setRootElement(new Element("root"));

CDATA node = new CDATA("hello alt=]]>");

//throw Exception

//node.setText("hello]]>");

Element ele = new Element("hello");

ele.setContent(node);

Element root = doc.getRootElement();

root.getChildren().add(ele);

XMLOutputter outputter = new XMLOutputter();

Format aFormat = Format.getCompactFormat();

aFormat.setEncoding("GB2312");

String sResult = outputter.outputString(doc.getRootElement().getChildren());

print(sResult);

}

}

编译并运行上面的代码结果,我们可以看到JDom无法设置Cdata的值为"]]>",会报异常.从xml字符串读出cdata的结果也没有把字串"]]>"翻译为"]]>".

接着再来测试Dom4J:

package com.xml.test;

import java.io.StringReader;

import org.dom4j.*;

import org.dom4j.io.SAXReader;

import org.dom4j.tree.DefaultCDATA;

/**

* 测试XML的CData数据类型.

*

* @author scud http://www.jscud.com

*

*/

public class Dom4jXmlTest extends XmlTestBase

{

public static void main(String[] args) throws Exception

{

readDocument();

print("===========================");

createDocument();

}

public static void createDocument()

{

Document document = DocumentHelper.createDocument();

Element root = document.addElement( "root" );

DefaultCDATA cdata = new DefaultCDATA("sample]]>");

DefaultCDATA cdata2 = new DefaultCDATA("sample]]>");

Element anode = root.addElement("cdata");

anode.add(cdata);

print(anode.getText());

print(anode.asXML());

Element anode2 = root.addElement("cdata2");

anode2.add(cdata2);

print(anode2.getText());

print(anode2.asXML());

}

public static void readDocument() throws Exception

{

StringReader strreader = new StringReader(xmlpart);

SAXReader reader = new SAXReader();

Document document = reader.read(strreader);

Node node = document.selectSingleNode( "//test/hello" );

print(node.getText());

print(node.getStringValue());

}

}

我们可以看到Dom4j也是没有做任何处理,输入的时候不作任何转换,原样输出,这样必然导致xml错误.读出的时候也没有做转换.

根据上面的测试我们可以得出结论:很多xml解析器没有正确解析cdata的数据,(jdom和dom4j用的人比较多),不要太相信这些解析器.

2.我们再来看看阅读RSS的RSS阅读器吧,例如FeedDemon和POTU,我们准备了一个CData类型的description字段,来进行测试.

内容:

Some Where

http://www.jscud.com/

Test

http://www.jscud.com

scud

Mon, 22 Aug 2005 10:22:22 GMT

<hr>

]]>

]]>

结果:

1.POTU没有做任何处理

2.FeedDemon做了处理,不过同时也把其他的> <等等都翻译了,这就更不对了..

本来我是打算在RSS里使用CDATA类型的description字段的,经过几番试验和测试,最后决定还是使用普通的description字段了,不在使用CDATA了.

CDATA? 鸡肋乎? 呵呵

posted on 2005-08-22 18:49 Scud(飞云小侠) 阅读(2515) 评论(0)  编辑  收藏 所属分类: Java

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要修改XMLCDATA区域的某个节点,可以使用Java的DOM解析器和XPath表达式。 首先,使用DOM解析器将XML文件解析为DOM树。然后,使用XPath表达式选择要修改的节点。最后,使用DOM API修改该节点的值,并将DOM树写回到XML文件。 以下是一个示例代码: ```java import java.io.File; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; import org.w3c.dom.Document; import org.w3c.dom.Node; public class ModifyCDATANode { public static void main(String[] args) throws Exception { // Load XML file DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(new File("input.xml")); // Select CDATA node using XPath XPathFactory xPathfactory = XPathFactory.newInstance(); XPath xpath = xPathfactory.newXPath(); XPathExpression expr = xpath.compile("//myNode/text()"); Node node = (Node) expr.evaluate(doc, XPathConstants.NODE); // Modify CDATA value node.setNodeValue("new value"); // Write DOM tree back to XML file TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); DOMSource source = new DOMSource(doc); StreamResult result = new StreamResult(new File("output.xml")); transformer.transform(source, result); } } ``` 在上面的示例,我们选择了名为“myNode”的节点,并将其值修改为“new value”。最后,我们将修改后的DOM树写回到名为“output.xml”的文件

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值