2013-09-19 2 views
1

Я хотел бы проанализировать XML-файл, и я использую оценку Java и xpath.Анализ XML-файла с использованием выражений XPATH и Java

Я хотел бы вывести родной узел текущего узла с выражением xpath и без с использованием функции getNextSibling(), возможно ли это?

например. если мы читаем элемент name, я бы хотел добавить выражение xpath = «./ address» , чтобы вывести родного брата «имя» без использования getNextSibling() /.

файл XML выглядит следующим образом:

<root>    
     <name> 
     <address> 
     <profession> 
    </root> 

Мой код выглядит следующим образом:

package dom_stack4; 

    import org.w3c.dom.*; 
    import javax.xml.xpath.*; 
    import javax.xml.parsers.*; 
    import java.io.IOException; 
    import org.xml.sax.SAXException; 


    public class Dom_stack4 { 

public static void main(String[] args) throws ParserConfigurationException,  SAXException, 
    IOException, XPathExpressionException { 
    // TODO code application logic here 


    DocumentBuilderFactory domFactory = 
    DocumentBuilderFactory.newInstance(); 
    domFactory.setNamespaceAware(true); 
    DocumentBuilder builder = domFactory.newDocumentBuilder(); 
    Document doc = builder.parse("root.xml"); 
    XPath xpath = XPathFactory.newInstance().newXPath(); 
    // XPath Query for showing all nodes value 
    XPathExpression expr = xpath.compile("/root/name/text()"); 

    Object result = expr.evaluate(doc, XPathConstants.NODESET); 
    NodeList nodes = (NodeList) result; 
    for (int i = 0; i < nodes.getLength(); i++) { 
      System.out.println(" Name is : " + nodes.item(i).getNodeValue()); 

      /* IS that possible here ?? */ 
     /* ./address/text() => outputs the current's node sibling */ 
      expr = xpath.compile("./address/text()"); 
      Object result1 = expr.evaluate(doc, XPathConstants.NODESET); 
      NodeList nodes1 = (NodeList) result1; 
      for (int j = 0; j < nodes1.getLength(); j++) { 
       System.out.println(" ---------------- " + nodes1.item(j).getNodeValue()); 
       } 

    } 
    } 
    } 

Спасибо, заранее

ответ

2

Во-первых, это было бы хорошо, если вы работаете ваш код с использованием правильно сформированного xml, теги имени и профессии должны быть закрыты, или вы получите сообщение об ошибке при попытке его проанализировать. Во-вторых, если вы хотите, чтобы выбрать текстовый дочерний узел, вам необходимо убедиться, что на самом деле что-то есть, так что ваш XML должен выглядеть следующим образом:

<root> 
    <name>hi</name> 
    <address>hi</address> 
    <profession>hi</profession> 
</root> 

Теперь, что у вас есть для выделения текста элемента имени в порядке, поэтому, начиная с вашего комментария IS that possible here ??, необходимо внести некоторые изменения.

Если вы хотите оценить относительный XPath, вы не хотите передавать объект документа методу оценки XPath. Текущее местоположение, в котором оценивается XPath, определяется элементом, который вы ему указываете, и объект документа всегда оценивается в корне. Если вы хотите оценивать относительно определенного узла, а не давать ему документ, дайте ему этот узел.

Таким образом, вы бы что-то подобное для вашей оценки вызова метода:

Object result1 = expr.evaluate(nodes.item(i), XPathConstants.NODESET); 

Далее, вы должны убедиться, что ваш XPath является на самом деле правильно. Выбранный нами узел является текстовым узлом имени. Это означает, что нам нужно сначала перейти на узел имени вместо текстового узла. Выражение . в синтаксисе XPath выбирает текущий узел, поэтому все, что вы делаете с этим, выбирает один и тот же узел. Вам нужно выражение .., которое выбирает родительский узел.

Итак, с нашим текущим XPath .. мы выбираем узел имени. Нам нужно выбрать узлы адреса, которые являются сибилизациями узла имени. Мы можем сделать это двумя способами: мы можем выбрать родителя узла имени, корневой узел и выбрать узлы адреса, которые являются дочерними, или мы могли бы использовать ось XPath для выбора братьев и сестер (информация о осях может быть здесь http://www.w3schools.com/xpath/xpath_axes.asp)

Если мы будем через корневой узел, мы должны были бы выбрать родитель родителя нашего текущего узла так ../.., который дает нам корневой узел, а затем адрес детьми: ../../address/text(), которая дайте нам все адреса братьев и сестер.

Кроме того, с помощью оси, мы могли бы сделать .. выбрать узел имя с последующим ../following-sibling::address (Примечание: это работает только, если адрес узлы после имя узла), а затем выберите текст адреса узлов с ../following-sibling:address/text().

Это дает нам эти две строки как либо

expr = xpath.compile("../../address/text()"); 
Object result1 = expr.evaluate(nodes.item(i), XPathConstants.NODESET); 

или

expr = xpath.compile("../following-sibling::address/text()"); 
Object result1 = expr.evaluate(nodes.item(i), XPathConstants.NODESET); 
Смежные вопросы