Как получить конкретные элементы XML с определенным значением атрибута? - PullRequest
29 голосов
/ 09 декабря 2011

Я пытаюсь проанализировать XML-файл из URL, взяв все элементы "<Type>", где указан параметр type_id = "4218" ??

Документ XML:

<BSQCUBS Version="0.04" Date="Fri Dec 9 11:43:29 GMT 2011" MachineDate="Fri, 09 Dec 2011 11:43:29 +0000">
  <Class class_id="385">
    <Title>Football Matches</Title>
    <Type type_id="4264" type_minbet="0.1" type_maxbet="2000.0">
      ...
    </Type>
    <Type type_id="5873" type_minbet="0" type_maxbet="0">
      ...
    </Type>
    <Type type_id="4725" type_minbet="0.1" type_maxbet="2000.0">
      ...
    </Type>
    <Type type_id="4218" type_minbet="0.1" type_maxbet="2000.0">
      ...
    </Type>
    <Type type_id="4221" type_minbet="0.1" type_maxbet="2000.0">
      ...
    </Type>
    <Type type_id="4218" type_minbet="0.1" type_maxbet="2000.0">
      ...
    </Type>
    <Type type_id="4299" type_minbet="0.1" type_maxbet="2000.0">
      ...
    </Type>
  </Class>
</BSQCUBS>

Вот мой код Java:

 DocumentBuilder db = dbf.newDocumentBuilder();
 Document doc = db.parse(new URL("http://cubs.bluesq.com/cubs/cubs.php?action=getpage&thepage=385.xml").openStream());

 doc.getDocumentElement().normalize();

 NodeList nodeList = doc.getElementsByTagName("Type");
 System.out.println("ukupno:"+nodeList.getLength());
 if (nodeList != null && nodeList.getLength() > 0) {
   for (int j = 0; j < nodeList.getLength(); j++) {
     Element el = (org.w3c.dom.Element) nodeList.item(j);
     type_id = Integer.parseInt(el.getAttribute("type_id"));
     System.out.println("type id:"+type_id);
   }
 }

Этот код дает мне все элементы, я не хочу этого, я хочу все элементы, где атрибут type_id = "4218"!

Ответы [ 5 ]

28 голосов
/ 09 декабря 2011

XPath - правильный выбор для вас:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("<Your xml doc uri>");
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("//Type[@type_id=\"4218\"]");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

И итерация по nl

7 голосов
/ 09 декабря 2011

В вашем цикле отсутствует условие:

 if(nodeList != null && nodeList.getLength() > 0){
     for (int j = 0; j < nodeList.getLength(); j++) {
         Element el = (org.w3c.dom.Element) nodeList.item(j);
         if (el.hasAttribute("type_id") && el.getAttribute("type_id").equals("4218")) {
              type_id = Integer.parseInt(el.getAttribute("type_id"));

              System.out.println("type id:"+type_id);
         }
     }
}

Также вам не нужно проверять, является ли NodeList, возвращаемый getElementsByTagName, нулевым, чтобы вы могли удалить цикл if перед циклом.

В общем случае вам лучше использовать XPath.

5 голосов
/ 09 декабря 2011

Вы можете использовать XPath. XPath используется для навигации по элементам и атрибутам в документе XML. Есть несколько хороших реализаций Xpath в Java.

Для вас пример

XPath xpath = XPathFactory.newInstance().newXPath();
XPathExpression expr = xpath.compile("//Type[@type_id=\"4218\"]");
Object exprResult = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodeList = (NodeList) exprResult;
3 голосов
/ 17 июня 2013

следуйте ответу @soulcheck ниже и, если возможно, поместите оператор перерыва ... который может улучшить ваш поиск.

 if(nodeList != null && nodeList.getLength() > 0){
 for (int j = 0; j < nodeList.getLength(); j++) {
     Element el = (org.w3c.dom.Element) nodeList.item(j);
     if (el.hasAttribute("type_id") && el.getAttribute("type_id").equals("4218")) {
          type_id = Integer.parseInt(el.getAttribute("type_id"));

          System.out.println("type id:"+type_id);
          break;

     }
 }

}

2 голосов
/ 09 декабря 2011

Следующий XPath даст вам элементы Type, которые вы ищете:

/BSQCUBS/Class/Type[@type_id=4218]

Таким образом, вы можете использовать следующий код Java, чтобы получить NodeList, который включает только эти:

XPathExpression expr = xpath.compile("/BSQCUBS/Class/Type[@type_id=4218]");
NodeList nl = (NodeList)expr.evaluate(doc, XPathConstants.NODESET);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...