2015-09-20 4 views
2

у меня есть файл XML, который выглядит как:Как выбрать узлы с разными тегами с помощью DOM?

<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?> 
<HWData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <NE MOID="WBTS-42" NEType="WBTS"> 
    <EQHO MOID="EQHO-1-0" > 
    <UNIT MOID="UNIT-FAN-1" State="enabled"></UNIT> 
    <UNIT MOID="UNIT-FAN-3" State="enabled"></UNIT> 
    </EQHO> 
    </NE> 
    <NE MOID="RNC-40" NEType="RNC"> 
    <EQHO MOID="EQHO-3-0" > 
    <UNIT MOID="UNIT-FAN-5" State="disabled"></UNIT> 
    <UNIT MOID="UNIT-FAN-6" State="disabled"></UNIT> 
    </EQHO> 
    </NE> 
</HWData> 

я прошу, как я могу получить NodeList содержащий «NE» и теги «UNIT» с помощью DOM? благодаря

+0

Вы запрашиваете «NodeList» с ** 6 ** значениями? Я имею в виду, что 6 элементов со следующими идентификаторами MOID: 'WBTS-42',' UNIT-FAN-1', 'UNIT-FAN-3',' RNC-40', 'UNIT-FAN-5',' UNIT- FAN-6' – Andreas

+0

да, это так! –

+0

В DOM нет встроенного метода. Вы можете получить два NodeLists, один для элементов 'NE' и один для элементов' UNIT'. Вы могли бы использовать XPath. Подробнее см. Это [javadoc] (http://docs.oracle.com/javase/7/docs/api/javax/xml/xpath/package-summary.html). – Andreas

ответ

1

попробовать это:

public static List<String> MOIDList(File file) throws SAXException, IOException, ParserConfigurationException, XPathExpressionException{ 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    DocumentBuilder db = dbf.newDocumentBuilder(); 
    Document doc = db.parse(file); 

     XPath xPath = XPathFactory.newInstance().newXPath(); 
     XPathExpression exp = xPath.compile("//NE | //UNIT"); 
     NodeList nl = (NodeList)exp.evaluate(doc, XPathConstants.NODESET); 

     List<String> MoidList = new ArrayList<>(); 
    for (int i = 0; i < nl.getLength(); i++) { 
     String moid=((Element)nl.item(i)).getAttribute("MOID"); 
      MoidList.add(moid); 
    } 
    return MoidList; 

} 
2

Вы можете сделать это вручную:

import java.io.File; 
import java.util.Arrays; 
import java.util.HashSet; 
import java.util.Set; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 

import org.w3c.dom.Document; 
import org.w3c.dom.Node; 
import org.w3c.dom.NodeList; 

public class XmlDomTest { 
    public static void main(String[] args) throws Exception { 
     File file = new File("/path/to/your/file"); 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 
     Document doc = db.parse(file); 
     Set<String> filteredNames = new HashSet<String>(Arrays.asList("NE", "UNIT")); 
     NodeList list = collectNodes(doc, filteredNames); 
     for (int i = 0; i < list.getLength(); i++) 
      System.out.println(list.item(i).getNodeName()); 
    } 

    private static NodeList collectNodes(Document doc, Set<String> filteredNames) { 
     Node ret = doc.createElement("NodeList"); 
     collectNodes(doc, filteredNames, ret); 
     return ret.getChildNodes(); 
    } 

    private static void collectNodes(Node node, Set<String> filteredNames, Node ret) { 
     NodeList chn = node.getChildNodes(); 
     for (int i = 0; i < chn.getLength(); i++) { 
      Node child = chn.item(i); 
      if (filteredNames.contains(child.getNodeName())) 
       ret.appendChild(child); 
      collectNodes(child, filteredNames, ret); 
     } 
    } 
} 
1

XPath только выбрать MOIDS является //NE/@MOID | //UNIT/@MOID.

Вы должны взглянуть на мою открытую библиотеку Xml-parser-библиотека unXml. Он доступен по телефону Maven Central.

Вы можете сделать следующее:

import com.nerdforge.unxml.Parsing; 
import com.nerdforge.unxml.factory.ParsingFactory; 
import org.w3c.dom.Document; 
import java.util.List; 

public class Parser { 
    public List<String> parseXml(String xml){ 
     Parsing parsing = ParsingFactory.getInstance().create(); 
     Document document = parsing.xml().document(xml); 

     List<String> result = parsing 
      .arr("//NE/@MOID | //UNIT/@MOID", parsing.text()) 
      .as(String.class) 
      .apply(document); 
     return result; 
    } 
} 

parseXml возвращает результат:

[WBTS-42, UNIT-FAN-1, UNIT-FAN-3, RNC-40, UNIT-FAN-5, UNIT-FAN-6] 

Вы также можете создавать более сложные вложенные datastructures если вам нужно. Дайте мне комментарий здесь, если вам нужен пример о том, как это сделать.