Java:解析 RSS 提要时出错
Java: error while parsing a RSS feed
下面是代码。
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("http://rss.adnkronos.com/RSS_Politica.xml");
NodeList nodes = doc.getElementsByTagName("title");
for(int k=0; k < nodes.getLength(); k++) {
System.out.print(nodes.item(k));
}
}
RSS 提要的 link 如下:http://rss.adnkronos.com/RSS_Politica.xml
结果(在控制台中)如下:
null null null null null null null null null null null null null null
null null null null null null null
节点标题的值,如您在 xml 中所见,显然不为空。
结果后,显示以下错误(翻译自意大利语)。
Error: URI=http://rss.adnkronos.com/RSS_Politica.xml Line=1: The root
element "rss" must match the root DOCTYPE "null".
Error: URI=http://rss.adnkronos.com/RSS_Politica.xml Line=1: Document
is invalid: no grammar found.
查看您遇到的错误的验证选项。
就标题的空值而言,节点上的 toString 似乎只是 returns 空值,或者做了一些刚刚变为空值的事情。如果您将其更新为 System.out.print(nodes.item(k).getTextContent());
,它将打印出标题。
有两个问题。让我们先解决您可能最关心的问题。
您的 NodeList 中的节点是 Element 节点。实际的文本节点是它们的子节点。所以要得到你想要的值,你可以这样做:
nodes.item(k).getFirstChild().getNodeValue()
或(在本例中):
nodes.item(k).getTextContent()
我个人认为前者在进行一般解析时稍微更健壮,因为如果恰好有多个子节点,getTextContent() 将连接所有子节点的所有文本内容。
至于验证错误,默认情况下,当您执行 setValidating(true) 时,它正在寻找一个不存在的嵌入式 DTD,并且它正在向您抱怨。 tl;dr 是 setValidating(false).
如果你真的想要验证 RSS,你应该尝试找到一个非官方的(因为没有官方的)XSD 模式文件并设置它在您的 DocumentBuilderFactory 中。不过,在这种情况下对 RSS 使用 XSD 可能不值得,因为互联网上一半的 RSS 尽管完全可用,但可能无法通过验证:).
下面是代码。
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("http://rss.adnkronos.com/RSS_Politica.xml");
NodeList nodes = doc.getElementsByTagName("title");
for(int k=0; k < nodes.getLength(); k++) {
System.out.print(nodes.item(k));
}
}
RSS 提要的 link 如下:http://rss.adnkronos.com/RSS_Politica.xml
结果(在控制台中)如下:
null null null null null null null null null null null null null null null null null null null null null
节点标题的值,如您在 xml 中所见,显然不为空。
结果后,显示以下错误(翻译自意大利语)。
Error: URI=http://rss.adnkronos.com/RSS_Politica.xml Line=1: The root element "rss" must match the root DOCTYPE "null".
Error: URI=http://rss.adnkronos.com/RSS_Politica.xml Line=1: Document is invalid: no grammar found.
查看您遇到的错误的验证选项。
就标题的空值而言,节点上的 toString 似乎只是 returns 空值,或者做了一些刚刚变为空值的事情。如果您将其更新为 System.out.print(nodes.item(k).getTextContent());
,它将打印出标题。
有两个问题。让我们先解决您可能最关心的问题。
您的 NodeList 中的节点是 Element 节点。实际的文本节点是它们的子节点。所以要得到你想要的值,你可以这样做:
nodes.item(k).getFirstChild().getNodeValue()
或(在本例中):
nodes.item(k).getTextContent()
我个人认为前者在进行一般解析时稍微更健壮,因为如果恰好有多个子节点,getTextContent() 将连接所有子节点的所有文本内容。
至于验证错误,默认情况下,当您执行 setValidating(true) 时,它正在寻找一个不存在的嵌入式 DTD,并且它正在向您抱怨。 tl;dr 是 setValidating(false).
如果你真的想要验证 RSS,你应该尝试找到一个非官方的(因为没有官方的)XSD 模式文件并设置它在您的 DocumentBuilderFactory 中。不过,在这种情况下对 RSS 使用 XSD 可能不值得,因为互联网上一半的 RSS 尽管完全可用,但可能无法通过验证:).