2011-04-06 51 views
1

我有下面的XML,我試圖打印一些節點的值。例如,下面的代碼我想打印Java:解析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 

,而不是「標題」和「的Bigfish活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="[email protected]" 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="[email protected]" raw="bigfish" machine_tag="0">bigfish</tag> 
     <tag id="314160-2882550369-5558" author="[email protected]" raw="live" machine_tag="0">live</tag> 
     <tag id="314160-2882550369-29726586" author="[email protected]" 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> 

回答

2

您的photo元素中存在文本節點,在下例中標記爲XXXX。你得到這個文本節點。請注意,可能有多個相鄰的文本節點。您需要找到具有Element類型的第一個節點才能獲得owner元素。

<photo ...>XXXX 
XXXX<owner nsid="[email protected]" ... /> 

試試這個:

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,正是你所得到的)。

0

因爲當你打電話element.getChildNodes()您獲得的元素,其中包括像idsecret屬性的所有兒童。所以list.item(0)是一個屬性,這就是爲什麼你沒有得到你期望的結果。

getNodeName()返回null因爲屬性沒有節點名
getNodeValue()返回#text因爲屬性的值是一個文本節點,這反過來又保持該屬性的字符串值。

此外,請不要重新定義相同的變量(例如list)以重新使用完全不同的內容。這是非常糟糕的做法。

+0

我不認爲他在getChildNodes中獲取屬性,但他正在爲空白字符獲取文本節點。 – 2011-04-06 15:36:40

+0

XML除非在<[[CDATA]]> – 2011-04-06 15:39:54

+0

@ Travis中忽略空格,這是不正確的。首先,屬性*不被認爲是DOM中元素節點的子元素,其次,空白在默認情況下不被忽略。 CDATA只是語法糖,它與空白沒有特別的關係。 – 2011-04-06 15:41:13

-1

使用JAXB代替SAX/DOM將使這個火箭科學變得更容易。有關解釋,請參見this article。首先,編寫等效的XSD架構(可以省略不需要的節點);這裏是一個良好的開端:http://mojo.codehaus.org/jaxb2-maven-plugin/usage.html

<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插件生成類。

然後,寫一些代碼(並添加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」)而不是作品