2016-12-16 32 views
2

我在解析XML時遇到了一些問題。將XML解析爲Java - 獲取根屬性值

我創建了一個函數,其中參數是來自XML文件的某個「元素」。 找到後,我想返回根屬性的值。 這裏是我的代碼:

     FileInputStream file = new FileInputStream(new File("C:\\Users\\Grizzly\\Java\\Projet_16_17-20161214\\bdd.xml")); 
     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder builder = factory.newDocumentBuilder(); 
     Document doc = builder.parse(file); 
     doc.getDocumentElement().normalize(); 
     NodeList nList = doc.getElementsByTagName("type"); 
     for (int temp = 0; temp < nList.getLength(); temp++) 
     { 
      Node nNode = nList.item(temp); 
      if(nNode.toString().equalsIgnoreCase(element)) 
      { 
        Element eElement = (Element) nNode; 
        System.out.println("Taxe= "+ eElement.getAttribute("taxe")); 
      } 
     } 
    } 

如何做到這一點任何想法? 這是我的XML文件:

<?xml version="1.0"?> 

-<types> 


-<type id="Nourriture" taxe="0.1"> 

<element>pomme</element> 

<element>fraise</element> 

<element>fromage</element> 

<element>viande rouge </element> 

</type> 


-<type id="Matiere Premiere" taxe="0.2"> 

<element>fer</element> 

<element>polypropylene</element> 

</type> 


-<type id="Element Solide" taxe="0.3"> 

<element>voiture</element> 

<element>planche surf</element> 

<element>pistolet</element> 

</type> 

</types> 

在我的代碼,我試圖從節點列表獲取某個節點的元素,然後將其比作字符串「元素」,這是用戶的輸入,並如果它們匹配,它將檢查鏈接到它的稅的屬性值。

在此先感謝。

編輯:我越來越接近我所需要的:

NodeList nList = doc.getElementsByTagName("type"); 

for (int temp = 0; temp < nList.getLength(); temp++) 
    { 
     Node nNode = nList.item(temp); 
     NodeList nChildren = nNode.getChildNodes(); 
     Element eElement = (Element) nNode; 
     for(int i = 0; i < nChildren.getLength(); i++) 
     { 
      String onElement = eElement.getElementsByTagName("element").item(i).getTextContent(); 
      if(onElement.equalsIgnoreCase(element)) 
      { 
       System.out.println("id : " + eElement.getAttribute("id")); 
       System.out.println("taxe : " + eElement.getAttribute("taxe")); 
       break; 
      } 
     } 
} 

但它只能讀取第一個元素...和(i)項不工作。 有什麼想法?

回答

1

如果我理解正確的話,你想獲取具有特定名稱(element)至少一個子元素,所有的文檔節點的特定屬性(idtaxe)。

儘管可以通過迭代DOM並保持狀態來解決問題,但我寧願將此任務委託給XPath。 XPath的代碼看起來更乾淨,更易於維護。例如,要獲取所有具有屬性idtaxe以及子元素element的元素,可以使用XPath表達式,如//*[@id and @taxe element]。匹配的節點在一行中獲取。您可以簡單地迭代節點並收集屬性,如以下示例中所示。

public static void main(String args[]) { 
    String element = args.length > 0 ? args[0] : "element"; 

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    try { 
     DocumentBuilder builder = factory.newDocumentBuilder(); 
     FileInputStream file = new FileInputStream(new File("/some/file.xml")); 
     Document doc = builder.parse(file); 
     XPath xPath = XPathFactory.newInstance().newXPath(); 
     String expression = "//*[@id and @taxe and " + element + "]"; 
     NodeList nodeList = (NodeList) xPath.compile(expression) 
       .evaluate(doc, XPathConstants.NODESET); 
     for (int i = 0; i < nodeList.getLength(); i++) { 
      Node node = nodeList.item(i); 
      NamedNodeMap attributes = node.getAttributes(); 
      for (int j = 0; j < attributes.getLength(); j++) { 
       Node aNode = attributes.item(j); 
       System.out.printf(
        "%s: %s\n", 
        aNode.getNodeName(), 
        aNode.getNodeValue() 
       ); 
      } 
     } 
    } catch (Exception e) { 
     System.err.println(e.getMessage()); 
     System.exit(1); 
    } 
} 

樣本輸出

id: Nourriture 
taxe: 0.1 
id: Matiere Premiere 
taxe: 0.2 
id: Element Solide 
taxe: 0.3 

注意,上述打印父元素的所有屬性樣品。如果你只想打印特定的人,就可以了,很明顯,添加一個簡單的檢查是這樣的:

String aName = aNode.getNodeName(); 
if (aName.equals("taxe")) { // ... 

但實際上你可以過濾掉的XPath屬性:

String expression = "//*[ " + element + "]/@*[name() = 'id' or name() = 'taxe']"; 
NodeList nodeList = (NodeList) xPath.compile(expression) 
     .evaluate(doc, XPathConstants.NODESET); 
for (int i = 0; i < nodeList.getLength(); i++) { 
    Node node = nodeList.item(i); 
    System.out.printf("%s: %s\n", node.getNodeName(), node.getNodeValue()); 
} 

上面的XPath表達式獲取名稱等於idtaxe的所有屬性節點。如果你想要所有屬性,只需刪除最後一個條件:

String expression = "//*[ " + element + "]/@*";