2014-07-23 238 views
0

這是我現在的XML文件,它給了我不同字符的對話,或者至少它應該。我希望它能夠工作,以便我可以指定實體標識和選項/任務標識並獲取輸出。所以我該怎麼做?任何幫助表示讚賞,非常感謝。如何通過元素ID讀取XML?

<?xml version="1.0"?> 
<dialoge> 
<entity id="1"> <!-- questgiver --> 
    <quest id="1"> 
     <option id="1"> 
      <precondition>player has not started quest</precondition> 
      <output>hello there, can you kill 2 enemies for me?</output> 
     </option> 
     <option id="2"> 
      <precondition>player has completed quest and player has not...</precondition> 
      <output>thankyou, have a sword for your troubles.</output> 
     </option> 
     <option id="3"> 
      <precondition>player has not finished quest</precondition> 
      <output>you haven't finished yet.</output> 
     </option> 
     <option id="4"> 
      <outpur>thank you.</outpur> 
     </option> 
    </quest> 
</entity> 
<entity id="2"> <!-- villager --> 
    <option id="1"> 
     <precondition>village is being destroyed</precondition> 
     <output>our village is being destroyed, please help us!</output> 
    </option> 
    <option id="2"> 
     <precondition>village has been saved or destroyed</precondition> 
     <output>we will never forget this.</output> 
    </option> 
    <option id="3"> 
     <output>hello.</output> 
    </option> 
</entity> 
</dialoge> 

這是我目前有,但它不起作用。我知道這可能是一個愚蠢的問題,但我無法在網絡上的任何地方找到答案。謝謝。

public static void read() { 
    try { 
     File file = new File("text.xml"); 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 
     Document doc = db.parse(file); 
     doc.getDocumentElement().normalize(); 

     System.out.println("root of xml file " + doc.getDocumentElement().getNodeName()); 
     NodeList nodes = doc.getElementsByTagName("entity"); 
     System.out.println("=========================="); 

     for(int i = 0; i < nodes.getLength(); i++) { 
      Node node = nodes.item(i); 
      if(node.getNodeType() == Node.ELEMENT_NODE) { 
       Element element = (Element) node; 
         if(element.getElementsByTagName("entity").item(0).getTextContent().equals("output")) { 

       } 
       System.out.println("" + getValue("output", element)); 
      } 
     } 
    }catch(Exception e) { 
     e.printStackTrace(); 
    } 
} 

private static String getValue(String tag, Element element) { 
    NodeList nodes = element.getElementsByTagName(tag).item(0).getChildNodes(); 
    Node node = (Node) nodes.item(0); 
    return node.getNodeValue(); 
} 

回答

2

最簡單的方法可能是使用XPath ......

try { 
    File file = new File("text.xml"); 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    Document doc = db.parse(file); 
    doc.getDocumentElement().normalize(); 

    XPath xpath = XPathFactory.newInstance().newXPath(); 
    XPathExpression xExpress = xpath.compile("//*[@id='1']"); 
    NodeList nl = (NodeList) xExpress.evaluate(doc, XPathConstants.NODESET); 
    System.out.println("Found " + nl.getLength() + " matches"); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

XPath查詢//*[@id='1']會發現其中有屬性id1

有價文件中的所有節點看看WC3 XPath TutorialHow XPath works關於XPath的更多細節

+0

如果我想找到只爲'entity'標籤? :) – Braj

+0

'// entity [@ id ='1']'或'// entity'如果你想要所有的實體,不管id值 – MadProgrammer

+0

看到我的xml文件有兩個不同的元素與id的,他們都有孩子也有id的元素,我該如何去尋找它們?我會做實體[@ id ='1'],然後選擇[@ id ='1']嗎?謝謝,這似乎是一個很好的解決方案。 –

1

一般來說, DOM更容易使用,但在開始使用之前會分析entire XML,因爲SAX parser正在解析XML,並且遇到標籤開始(例如, <something>),則觸發startElement事件(事件的實際名稱可能不同)。 read more..

Java教程Parsing an XML File Using SAX

下面是示例代碼:

import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 

import org.xml.sax.Attributes; 
import org.xml.sax.SAXException; 
import org.xml.sax.helpers.DefaultHandler; 

public class GetElementAttributesInSAXXMLParsing extends DefaultHandler { 

    public static void main(String[] args) throws Exception { 
     DefaultHandler handler = new GetElementAttributesInSAXXMLParsing(); 
     SAXParserFactory factory = SAXParserFactory.newInstance(); 
     factory.setValidating(false); 
     SAXParser parser = factory.newSAXParser(); 
     parser.parse(new File("text.xml"), handler);  
    } 

    @Override 
    public void startElement(String uri, String localName, String qName, Attributes attributes) 
      throws SAXException { 

     System.out.println("Tag Name:"+qName); 
     // get the number of attributes in the list 
     int length = attributes.getLength(); 

     // process each attribute 
     for (int i = 0; i < length; i++) { 

      // get qualified (prefixed) name by index 
      String name = attributes.getQName(i); 
      System.out.println("Attribute Name:" + name); 

      // get attribute's value by index. 
      String value = attributes.getValue(i); 
      System.out.println("Attribute Value:" + value); 
     } 
    } 
} 
+0

感謝您發佈此信息,它非常有幫助,但我對startElement()感到困惑,在我看來它會自動調用,這是怎麼發生的?還有什麼是引用String uri,String localName等等的變量。謝謝你的幫助。 –

+0

@ user3053027它被稱爲訪客模式。 sax解析器會在讀取XML文檔時自動調用處理程序的方法以響應更改。如果您只想從頭到尾解析文檔一次,此方法非常有用。如果要分別查詢文檔,則需要使用DOM方法,這將允許您隨時跳到文檔中,隨意移動並執行重複查詢...... – MadProgrammer