Java Xml解析:通过缺少标记来区分两个Xml元素

时间:2014-07-11 08:51:44

标签: java xml parsing

从Web服务器请求我得到一个XML响应,其中包含我需要的数据。 它看起来像(摘录):

   <ctc:BasePrice>
  <cgc:PriceAmount amountCurrencyID="EUR">18.75</cbc:PriceAmount>
  <cgc:BaseQuantity quantityUnitCode="EA">1</cbc:BaseQuantity>
   </ctc:BasePrice>
  <ctc:BasePrice>
  <cgc:PriceAmount amountCurrencyID="EUR">18.25</cbc:PriceAmount>
  <cgc:BaseQuantity quantityUnitCode="EA">1</cbc:BaseQuantity>
  <cgc:MinimumQuantity quantityUnitCode="EA">3</cbc:MinimumQuantity>
  <ctc:BasePrice>

我需要的是第一个&#34; PriceAmount&#34;价值,可能是第二个不同的价格。 但是我怎样才能确保找到正确的一个,通过&#34;告诉&#34;解析器他应该采用不包含&#34; MinimumQuantity&#34;现场区分他们? 我在Sax等阅读了很多,但可以找到一个如何实现&#34;逻辑&#34;为了那个原因。 也许有人遇到了类似的问题。提前感谢每一个提示。

1 个答案:

答案 0 :(得分:0)

你可以使用xpath。表达式"//*[local-name()='MinimumQuantity']/../*[local-name()='PriceAmount']"应该返回您想要的内容。例如

import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class XpathParser {
    public static void main(String[] args) {

    try {
        String xml = "<root>"
                        + "<ctc:BasePrice>"
                            + "<cgc:PriceAmount amountCurrencyID=\"EUR\">18.75</cgc:PriceAmount>"
                            + "<cgc:BaseQuantity quantityUnitCode=\"EA\">1</cgc:BaseQuantity>"
                        + "</ctc:BasePrice>"
                        + "<ctc:BasePrice>"
                            + "<cgc:PriceAmount amountCurrencyID=\"EUR\">18.25</cgc:PriceAmount>"
                            + "<cgc:BaseQuantity quantityUnitCode=\"EA\">1</cgc:BaseQuantity>"
                            + "<cgc:MinimumQuantity quantityUnitCode=\"EA\">3</cgc:MinimumQuantity>"
                        + "</ctc:BasePrice>"
                    + "</root>";

        InputStream xmlStream = new ByteArrayInputStream(xml.getBytes());

        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();

        DocumentBuilder builder =  builderFactory.newDocumentBuilder();

        Document xmlDocument = builder.parse(xmlStream);

        XPath xPath =  XPathFactory.newInstance().newXPath();

        String expression = "//*[local-name() = 'BasePrice' and not(descendant::*[local-name() = 'MinimumQuantity'])]/*[local-name()='PriceAmount']";
        NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET);
        for (int i = 0; i < nodeList.getLength(); i++) {
        System.out.println(nodeList.item(i).getFirstChild().getNodeValue()); 
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (SAXException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    } catch (XPathExpressionException e) {
        e.printStackTrace();
    }       
    }
}

Dom Parser方式

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

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

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


public class DomParser{

    public static void main(String[] args) {
        try {
            String xml = "<root>"
                    + "<ctc:BasePrice>"
                        + "<cgc:PriceAmount amountCurrencyID=\"EUR\">18.75</cgc:PriceAmount>"
                        + "<cgc:BaseQuantity quantityUnitCode=\"EA\">1</cgc:BaseQuantity>"
                    + "</ctc:BasePrice>"
                    + "<ctc:BasePrice>"
                        + "<cgc:PriceAmount amountCurrencyID=\"EUR\">18.25</cgc:PriceAmount>"
                        + "<cgc:BaseQuantity quantityUnitCode=\"EA\">1</cgc:BaseQuantity>"
                        + "<cgc:MinimumQuantity quantityUnitCode=\"EA\">3</cgc:MinimumQuantity>"
                    + "</ctc:BasePrice>"
                    + "</root>";

            InputStream xmlStream = new ByteArrayInputStream(xml.getBytes());
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = builderFactory.newDocumentBuilder();
            Document xmlDocument = builder.parse(xmlStream);
            xmlDocument.getDocumentElement().normalize();

            NodeList nList = xmlDocument.getElementsByTagName("ctc:BasePrice");
            for (int temp = 0; temp < nList.getLength(); temp++) {
                Node nNode = nList.item(temp);
                if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element eElement = (Element) nNode;
                    if(eElement.getElementsByTagName("cgc:MinimumQuantity").getLength() == 0){
                        System.out.println(eElement.getElementsByTagName("cgc:PriceAmount").item(0).getTextContent());
                    }
                }
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 
    }

}