我有以下XML,我正在尝试打印某些节点的值。例如,使用以下代码我想打印
NodeList list = doc.getElementsByTagName("photo");
element = (Element)list.item(0);
list = element.getChildNodes();
System.out.println(list.item(0).getNodeName());
System.out.println(list.item(0).getNodeValue());
我得到了
null
#text
而不是“title”和“bigfish live 200812”
我做错了什么? 感谢
<?xml version="1.0" encoding="utf-8" ?>
<rsp stat="ok">
<photo id="2882550369" secret="21054282c8" server="3106" farm="4" dateuploaded="1222202793" isfavorite="0" license="0" safety_level="0" rotation="0" views="5" media="photo">
<owner nsid="64878451@N00" username="fishthemusic" realname="masayoshi yamamiya" location="kawasaki, japan" iconserver="4" iconfarm="1" />
<title>bigfish live 200812</title>
<description>photo by Kazuhiro Nakamura</description>
<visibility ispublic="1" isfriend="0" isfamily="0" />
<dates posted="1222202793" taken="2008-09-24 05:46:33" takengranularity="0" lastupdate="1222998937" />
<editability cancomment="1" canaddmeta="0" />
<publiceditability cancomment="1" canaddmeta="0" />
<usage candownload="1" canblog="1" canprint="0" canshare="1" />
<comments>0</comments>
<notes />
<tags>
<tag id="314160-2882550369-80673" author="64878451@N00" raw="bigfish" machine_tag="0">bigfish</tag>
<tag id="314160-2882550369-5558" author="64878451@N00" raw="live" machine_tag="0">live</tag>
<tag id="314160-2882550369-29726586" author="64878451@N00" raw="upcoming:event=1167424" machine_tag="1">upcoming:event=1167424</tag>
</tags>
<urls>
<url type="photopage">http://www.flickr.com/photos/fishthemusic/2882550369/</url>
</urls>
</photo>
</rsp>
答案 0 :(得分:3)
您的photo
元素中有文字节点,在下面的示例中标记为XXXX。你得到这个文本节点。请注意,可能存在多个相邻的文本节点。您需要找到具有Element类型的第一个节点才能获得owner
元素。
<photo ...>XXXX
XXXX<owner nsid="64878451@N00" ... />
请改为尝试:
NodeList list = doc.getElementsByTagName("photo");
element = (Element)list.item(0);
list = element.getChildNodes();
int ix = 0;
while (ix < list.getLength() && list.item(ix).getNodeType() != Node.ELEMENT_NODE) {
ix++;
}
// now ix points to your first element node (if there was one)
System.out.println(list.item(ix).getNodeName());
System.out.println(list.item(ix).getNodeValue());
顺便说一下,元素的“nodeValue”是null
,所以你应该看到
owner
null
作为输出。有关详细信息,另请参阅http://download.oracle.com/javase/6/docs/api/org/w3c/dom/Node.html。 (它还显示#text
是文本节点的nodeName,正是你得到的。)
答案 1 :(得分:0)
因为当您致电element.getChildNodes()
时,您将获得该元素的所有子项,其中包含id
和secret
等属性。所以list.item(0)
是一个属性,这就是为什么你没有得到你期望的结果。
getNodeName()
返回null
,因为属性没有节点名称
getNodeValue()
返回#text
,因为属性的值是文本节点,而文本节点又保存该属性的字符串值。
此外,请不要重新定义相同的变量(例如list
)以重新使用完全不同的内容。这真的很糟糕。
答案 2 :(得分:-1)
使用JAXB代替SAX / DOM将使这种火箭科学变得更加容易。有关说明,请参阅this article。
首先,编写等效的XSD架构(可以省略不需要的节点);这是一个好的开始:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="photo">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="owner" type="owner" />
<xsd:element name="title" type="xsd:string" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:int" />
<xsd:attribute name="secret" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:complexType name="owner">
<xsd:attribute name="nsid" type="xsd:string" />
</xsd:complexType>
</xsd:schema>
其次,使用此maven插件从此生成类:http://mojo.codehaus.org/jaxb2-maven-plugin/usage.html。
然后,编写一些代码(并将JAXB maven dependency添加到项目中):
public class JaxbTest {
@Test
public void should_parse_recipe() throws JAXBException {
URL xmlUrl = Resources.getResource("file.xml");
Photo recipe = parse(xmlUrl, Photo.class);
assertEquals(Integer.valueOf(15), recipe.getCooking().getDuration());
}
private <T> T parse(URL url, Class<T> clazz) throws JAXBException {
Unmarshaller unmarsh = JAXBContext.newInstance(clazz).createUnmarshaller();
return clazz.cast(unmarsh.unmarshal(url));
}
}
PS。 Resources.getResource
来自番石榴;使用Thread.currentThread()。getContextClassLoader()。getSystemResource(“file.xml”)代替工作