2012-10-19 101 views
1

我在解析Java中的XML文件時遇到了一些麻煩。該文件的形式爲:帶有重複標籤的XPath和Java

<root> 
    <thing> 
    <name>Thing1</name> 
    <property> 
     <name>Property1</name> 
    </property> 
    ... 
    </thing> 
    ... 
</root> 

最後,我想這個文件轉換成的事對象的列表,這將有一個String名稱(Thing1)和Property對象的名單,這將各自也有一個名字(Property1)。

我一直在試圖使用xpaths來獲取這些數據,但是當我試圖得到'thing'的名字時,它給了我所有出現在'thing'中的名字,包括那些「酒店的。我的代碼是:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
DocumentBuilder db = dbf.newDocumentBuilder(); 
Document dom = db.parse(filename); 
XPath xpath = XPathFactory.newInstance().newXPath(); 


XPathExpression thingExpr = xpath.compile("//thing"); 
NodeList things = (NodeList)thingExpr.evaluate(dom, XPathConstants.NODESET); 
for(int count = 0; count < things.getLength(); count++) 
{ 
    Element thing = (Element)things.item(count); 
    XPathExpression nameExpr = xpath.compile(".//name/text()"); 
    NodeList name = (NodeList) nameExpr.evaluate(thing, XPathConstants.NODESET); 
    for(int i = 0; i < name.getLength(); i++) 
    { 
     System.out.println(name.item(i).getNodeValue());  
    } 
} 

任何人都可以幫忙嗎?提前致謝!

+0

輸出,它似乎並不認爲你已經表示要生產使用什麼XPath - 即使考慮了評論。 Xpath用於選擇我們感興趣的某些特定節點 - 它們是在您的特定情況下?你想從這些特定節點提取哪些數據?請編輯問題並指定這些缺失和重要的信息。 –

回答

1

你可以嘗試像...

public class TestXPath { 

    public static void main(String[] args) { 
     String xml = 
         "<root>\n" 
         + " <thing>\n" 
         + "  <name>Thing1</name>\n" 
         + "  <property>\n" 
         + "   <name>Property1</name>\n" 
         + "  </property>\n" 
         + "  <property>\n" 
         + "   <name>Property2</name>\n" 
         + "  </property>\n" 
         + "  <property>\n" 
         + "   <name>Property3</name>\n" 
         + "  </property>\n" 
         + "  <property>\n" 
         + "   <name>Property4</name>\n" 
         + "  </property>\n" 
         + "  <property>\n" 
         + "   <name>Property5</name>\n" 
         + "  </property>\n" 
         + " </thing>/n" 
         + " <NoAThin>\n" 
         + "  <name>Thing2</name>\n" 
         + "  <property>\n" 
         + "   <name>Property1</name>\n" 
         + "  </property>\n" 
         + "  <property>\n" 
         + "   <name>Property2</name>\n" 
         + "  </property>\n" 
         + "  <property>\n" 
         + "   <name>Property3</name>\n" 
         + "  </property>\n" 
         + "  <property>\n" 
         + "   <name>Property4</name>\n" 
         + "  </property>\n" 
         + "  <property>\n" 
         + "   <name>Property5</name>\n" 
         + "  </property>\n" 
         + " </NoAThin>/n" 
         + "</root>"; 

     try { 
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
      DocumentBuilder db = dbf.newDocumentBuilder(); 
      ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes()); 
      Document dom = db.parse(bais); 
      XPath xpath = XPathFactory.newInstance().newXPath(); 

      // Find the "thing" node... 
      XPathExpression thingExpr = xpath.compile("/root/thing"); 
      NodeList things = (NodeList) thingExpr.evaluate(dom, XPathConstants.NODESET); 

      System.out.println("Found " + things.getLength() + " thing nodes..."); 

      // Find the property nodes of thing 
      XPathExpression expr = xpath.compile("property"); 
      NodeList nodes = (NodeList) expr.evaluate(things.item(0), XPathConstants.NODESET); 

      System.out.println("Found " + nodes.getLength() + " thing/property nodes..."); 

      // Find all the property "name" nodes under thing 
      expr = xpath.compile("property/name"); 
      nodes = (NodeList) expr.evaluate(things.item(0), XPathConstants.NODESET); 

      System.out.println("Found " + nodes.getLength() + " name nodes..."); 
      System.out.println("Property value = " + nodes.item(0).getTextContent()); 

      // Find all nodes that have property nodes 
      XPathExpression exprAll = xpath.compile("/root/*/property"); 
      NodeList nodesAll = (NodeList) exprAll.evaluate(dom, XPathConstants.NODESET); 
      System.out.println("Found " + nodesAll.getLength() + " property nodes..."); 

     } catch (Exception exp) { 
      exp.printStackTrace(); 
     } 
    } 
} 

,這將給你的像

Found 1 thing nodes... 
Found 5 thing/property nodes... 
Found 5 name nodes... 
Property value = Property1 
Found 10 property nodes... 
+0

這樣做,謝謝! – KritSandvich

0

"//thing/name/text()"怎麼樣?

您現在使用雙斜槓name表示「樹中的任何位置,不一定是直接的子節點」。

+0

這確實讓我得到了所有的名字,但是如果我稍後用屬性名稱做同樣的事情,我不知道如何匹配它們:/。之後我會使用「.//」,因爲我被告知這是一個相對xpath。 – KritSandvich

0

使用這些XPath表達式

//thing[name='Thing1'] 

這個選擇XML文檔中的任何thing元素,具有name的孩子,他的字符串值是"Thing1"

也使用

//property[name='Property1'] 

這個選擇XML文檔中的任何property元素,具有name的孩子,他的字符串值"Property1"

更新

要獲得所有文本節點,每個節點包含thing元素的字符串值,只是做

//thing/text() 

在XPath 2.0一個可以得到的序列字符串本身,使用:

//thing/string(.) 

這不是possi與單個XPath表達式竹葉提取,但可以得到一個特定(第n個)thing元件這樣的字符串值:

string((//thing)[$n]) 

$n其中必須以特定數量被取代1至count(//thing)。從1至cnt$n循環

count(//thing) 

,然後動態生成的XPath表達式並評價它:

因此,在你prograaming語言,可以先通過評估該XPath表達式確定cnt

string((//thing)[$n]) 

與獲得property元素的所有值完全相同。

+0

這是假設我已經知道事物的名稱,我不......這就是我正在尋找:) – KritSandvich

+0

@KritSandvich:請參閱我的答案的更新。 –