我正在制作一个练习应用程序,目的是从RSS源中读取数据。
到目前为止它已经很顺利,除了我的应用程序遇到特殊字符的问题。它读取节点中的第一个特殊字符,然后移动到下一个节点。
非常感谢任何帮助,对于随后的大型代码块感到抱歉。
RSS Feed - www.usu.co.nz/usu-news/rss.xml
<title>Unitec hosts American film students</title>
<link>http://www.usu.co.nz/node/4640</link>
<description><p>If you’ve been hearing American accents around the Mt Albert campus over the past week.</description>
显示代码
String xml = XMLFunctions.getXML();
Document doc = XMLFunctions.XMLfromString(xml);
NodeList nodes = doc.getElementsByTagName("item");
for (int i = 0; i < nodes.getLength(); i++)
{
Element e = (Element)nodes.item(i);
Log.v("XMLTest", XMLFunctions.getValue(e, "title"));
Log.v("XMLTest", XMLFunctions.getValue(e, "link"));
Log.v("XMLTest", XMLFunctions.getValue(e, "description"));
Log.v("XMLTest", XMLFunctions.getValue(e, "pubDate"));
Log.v("XMLTest", XMLFunctions.getValue(e, "dc:creator"));
}
读者代码
public class XMLFunctions
{
public final static Document XMLfromString(String xml)
{
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
System.out.println("XML parse error: " + e.getMessage());
return null;
} catch (SAXException e) {
System.out.println("Wrong XML file structure: " + e.getMessage());
return null;
} catch (IOException e) {
System.out.println("I/O exeption: " + e.getMessage());
return null;
}
return doc;
}
/** Returns element value
* @param elem element (it is XML tag)
* @return Element value otherwise empty String
*/
public final static String getElementValue( Node elem ) {
Node kid;
if(elem != null)
{
if (elem.hasChildNodes())
{
for(kid = elem.getFirstChild(); kid != null; kid = kid.getNextSibling())
{
if( kid.getNodeType() == Node.TEXT_NODE )
{
return kid.getNodeValue();
}
}
}
}
return "";
}
public static String getXML(){
String line = null;
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://www.usu.co.nz/usu-news/rss.xml");
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
line = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
} catch (MalformedURLException e) {
line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
} catch (IOException e) {
line = "<results status=\"error\"><msg>Can't connect to server</msg></results>";
}
return line;
}
public static int numResults(Document doc){
Node results = doc.getDocumentElement();
int res = -1;
try{
res = Integer.valueOf(results.getAttributes().getNamedItem("count").getNodeValue());
}catch(Exception e ){
res = -1;
}
return res;
}
public static String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return XMLFunctions.getElementValue(n.item(0));
}
}
输出
Unitec hosts American film students
http://www.usu.co.nz/node/4640
<
Wed, 01 Aug 2012 05:43:22 +0000
Phillipa
答案 0 :(得分:3)
您的代码仅从元素中提取第一个子文本节点。 DOM规范允许多个相邻的文本节点,所以我怀疑这里发生的是你的解析器代表<
,p
,>
和剩下的文本为(at)至少)四个单独的文本节点。您需要将节点连接成一个字符串,或者在包含元素节点上调用normalize()
(它修改DOM树以将相邻文本节点合并为一个)。
有各种图书馆可以帮助您。例如,如果您的应用程序使用Spring框架,则org.springframework.util.xml.DomUtils
具有getTextValue
静态方法,该方法将从元素中提取完整的文本值。
答案 1 :(得分:2)
你的功能
public final static String getElementValue( Node elem ) {
Node kid;
if(elem != null)
{
if (elem.hasChildNodes())
{
for(kid = elem.getFirstChild(); kid != null; kid = kid.getNextSibling())
{
if( kid.getNodeType() == Node.TEXT_NODE )
{
return kid.getNodeValue();
}
}
}
}
return "";
}
返回给定元素下的第一个文本节点。单个标记中的一大块文本可以拆分为多个文本节点,这通常会在存在特殊字符时发生。
您应该将所有文本节点附加到字符串中以获取返回值。
大概像这样的东西可能会起作用:
public final static String getElementValue( Node elem ) {
if ((elem == null) || (!(elem.hasChildNodes())))
return "";
Node kid;
StringBuilder builder = new StringBuilder();
for(kid = elem.getFirstChild(); kid != null; kid = kid.getNextSibling())
{
if( kid.getNodeType() == Node.TEXT_NODE )
{
builder.append(kid.getNodeValue());
}
}
return builder.toString();
}
答案 2 :(得分:1)
稍微偏离主题,但您可能想要查看已有的RSS框架之一,例如ROME。比重新发明轮子好。
答案 3 :(得分:0)
<?xml version="1.0" encoding="UTF-8"?>
。也没有根元素。
答案 4 :(得分:0)
您确定DefaultHttpClient未转换XML字符串吗? 我尝试了你的代码并改变了方法XMLFunctions.getXML()来直接提供XML字符串,而不是通过DefaultHttpClient获取它,输出就像
Unitec hosts American film students
http://www.usu.co.nz/node/4640
<p>If you’ve been hearing American accents around the Mt Albert campus over the past week.
正如所料。