2016-12-16 97 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 + "]/@*";