簡體   English   中英

如何使用 Java 檢索 XML 的元素值?

[英]How to retrieve element value of XML using Java?

我是 XML 的新手。 我想根據請求名稱閱讀以下 XML。 請幫助我如何在 Java 中閱讀以下 XML -

<?xml version="1.0"?>
    <config>
        <Request name="ValidateEmailRequest">
            <requestqueue>emailrequest</requestqueue>
            <responsequeue>emailresponse</responsequeue>
        </Request>
        <Request name="CleanEmail">
            <requestqueue>Cleanrequest</requestqueue>
            <responsequeue>Cleanresponse</responsequeue>
        </Request>
    </config>

如果您的 XML 是字符串,那么您可以執行以下操作:

String xml = ""; //Populated XML String....

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(xml)));
Element rootElement = document.getDocumentElement();

如果您的 XML 在文件中,那么Document document將像這樣實例化:

Document document = builder.parse(new File("file.xml"));

document.getDocumentElement()返回作為文檔的文檔元素的節點(在您的情況下為<config> )。

一旦你有了rootElement ,你就可以訪問元素的屬性(通過調用rootElement.getAttribute()方法)等。 有關 java org.w3c.dom.Element 的更多方法

有關 java DocumentBuilderDocumentBuilderFactory 的更多信息。 請記住,提供的示例創建了一個 XML DOM 樹,因此如果您有大量的 XML 數據,該樹可能會很大。


更新這是獲取元素<requestqueue> “值”的<requestqueue>

protected String getString(String tagName, Element element) {
        NodeList list = element.getElementsByTagName(tagName);
        if (list != null && list.getLength() > 0) {
            NodeList subList = list.item(0).getChildNodes();

            if (subList != null && subList.getLength() > 0) {
                return subList.item(0).getNodeValue();
            }
        }

        return null;
    }

您可以有效地將其稱為,

String requestQueueName = getString("requestqueue", element);

如果您只需要從 xml 中檢索一個(第一個)值:

public static String getTagValue(String xml, String tagName){
    return xml.split("<"+tagName+">")[1].split("</"+tagName+">")[0];
}

如果您想解析整個 xml 文檔,請使用 JSoup:

Document doc = Jsoup.parse(xml, "", Parser.xmlParser());
for (Element e : doc.select("Request")) {
    System.out.println(e);
}

如果您只是想從 XML 中獲取單個值,您可能需要使用 Java 的 XPath 庫。 例如,請參閱我對上一個問題的回答:

它看起來像:

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

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

public class Demo {

    public static void main(String[] args) {
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder builder = domFactory.newDocumentBuilder();
            Document dDoc = builder.parse("E:/test.xml");

            XPath xPath = XPathFactory.newInstance().newXPath();
            Node node = (Node) xPath.evaluate("/Request/@name", dDoc, XPathConstants.NODE);
            System.out.println(node.getNodeValue());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

有許多不同的方法可以做到這一點。 您可能想查看XStreamJAXB 有教程和例子。

如果 XML 格式正確,那么您可以將其轉換為 Document。 通過使用 XPath,您可以獲得 XML 元素。

String xml = "<stackusers><name>Yash</name><age>30</age></stackusers>";

形成 XML-String 創建文檔並使用其 XML-Path 查找元素。

Document doc = getDocument(xml, true);

    public static Document getDocument(String xmlData, boolean isXMLData) throws Exception {
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        dbFactory.setNamespaceAware(true);
        dbFactory.setIgnoringComments(true);
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc;
        if (isXMLData) {
            InputSource ips = new org.xml.sax.InputSource(new StringReader(xmlData));
            doc = dBuilder.parse(ips);
        } else {
            doc = dBuilder.parse( new File(xmlData) );
        }
        return doc;
    }

使用org.apache.xpath.XPathAPI來獲取 Node 或 NodeList。

System.out.println("XPathAPI:"+getNodeValue(doc, "/stackusers/age/text()"));

NodeList nodeList = getNodeList(doc, "/stackusers");
System.out.println("XPathAPI NodeList:"+ getXmlContentAsString(nodeList));
System.out.println("XPathAPI NodeList:"+ getXmlContentAsString(nodeList.item(0)));

    public static String getNodeValue(Document doc, String xpathExpression) throws Exception {
        Node node = org.apache.xpath.XPathAPI.selectSingleNode(doc, xpathExpression);
        String nodeValue = node.getNodeValue();
        return nodeValue;
    }
    public static NodeList getNodeList(Document doc, String xpathExpression) throws Exception {
        NodeList result = org.apache.xpath.XPathAPI.selectNodeList(doc, xpathExpression);
        return result;
    }

使用javax.xml.xpath.XPathFactory

System.out.println("javax.xml.xpath.XPathFactory:"+getXPathFactoryValue(doc, "/stackusers/age"));

    static XPath xpath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
    public static String getXPathFactoryValue(Document doc, String xpathExpression) throws XPathExpressionException, TransformerException, IOException {
        Node node = (Node) xpath.evaluate(xpathExpression, doc, XPathConstants.NODE);
        String nodeStr = getXmlContentAsString(node);
        return nodeStr;
    }

使用文檔元素。

System.out.println("DocumentElementText:"+getDocumentElementText(doc, "age"));

    public static String getDocumentElementText(Document doc, String elementName) {
        return doc.getElementsByTagName(elementName).item(0).getTextContent();
    }

獲取兩個字符串之間的值。

String nodeVlaue = org.apache.commons.lang.StringUtils.substringBetween(xml, "<age>", "</age>");
System.out.println("StringUtils.substringBetween():"+nodeVlaue);

完整示例:

public static void main(String[] args) throws Exception {
    String xml = "<stackusers><name>Yash</name><age>30</age></stackusers>";
    Document doc = getDocument(xml, true);
    
    String nodeVlaue = org.apache.commons.lang.StringUtils.substringBetween(xml, "<age>", "</age>");
    System.out.println("StringUtils.substringBetween():"+nodeVlaue);
    
    System.out.println("DocumentElementText:"+getDocumentElementText(doc, "age"));
    System.out.println("javax.xml.xpath.XPathFactory:"+getXPathFactoryValue(doc, "/stackusers/age"));
    
    System.out.println("XPathAPI:"+getNodeValue(doc, "/stackusers/age/text()"));
    NodeList nodeList = getNodeList(doc, "/stackusers");
    System.out.println("XPathAPI NodeList:"+ getXmlContentAsString(nodeList));
    System.out.println("XPathAPI NodeList:"+ getXmlContentAsString(nodeList.item(0)));
}
public static String getXmlContentAsString(Node node) throws TransformerException, IOException {
    StringBuilder stringBuilder = new StringBuilder();
    NodeList childNodes = node.getChildNodes();
    int length = childNodes.getLength();
    for (int i = 0; i < length; i++) {
        stringBuilder.append( toString(childNodes.item(i), true) );
    }
    return stringBuilder.toString();
}

輸出:

StringUtils.substringBetween():30
DocumentElementText:30
javax.xml.xpath.XPathFactory:30
XPathAPI:30
XPathAPI NodeList:<stackusers>
   <name>Yash</name>
   <age>30</age>
</stackusers>
XPathAPI NodeList:<name>Yash</name><age>30</age>

有兩種通用方法可以做到這一點。 您將創建該 XML 文件的域對象模型,看看這個

第二種選擇是使用事件驅動解析,這是 DOM xml 表示的替代方法。 恕我直言,你可以找到的這兩個基本技術的最佳整體比較這里 當然,有關處理 xml 的知識還有很多,例如,如果給定了 XML 模式定義 (XSD),則可以使用JAXB

有多種 API 可用於通過 Java 讀/寫 XML 文件。 我會參考使用StaX

這也很有用 - Java XML APIs

由於您使用它進行配置,因此您最好的選擇是 apache commons-configuration 對於簡單文件,它比“原始”XML 解析器更易於使用。

請參閱XML 操作方法

您可以創建一個擴展 org.xml.sax.helpers.DefaultHandler 的類並調用

start_<tag_name>(Attributes attrs);

end_<tag_name>();

因為它是:

start_request_queue(attrs);

等等。

然后擴展該類並實現您想要的 xml 配置文件解析器。 例子:

...
  public void startElement(String uri, String name, String qname,
                           org.xml.sax.Attributes attrs) 
                  throws org.xml.sax.SAXException {
    Class[] args = new Class[2];
    args[0] = uri.getClass();
    args[1] = org.xml.sax.Attributes.class;
    try {
      String mname = name.replace("-", "");
      java.lang.reflect.Method m = 
            getClass().getDeclaredMethod("start" + mname, args);
      m.invoke(this, new Object[] { uri, (org.xml.sax.Attributes)attrs }); 
    }
catch (IllegalAccessException e) { throw new RuntimeException(e); }
catch (NoSuchMethodException e) { throw new RuntimeException(e); }
catch (java.lang.reflect.InvocationTargetException e) { org.xml.sax.SAXException se = new org.xml.sax.SAXException(e.getTargetException()); se.setStackTrace(e.getTargetException().getStackTrace()); }

並在特定的配置解析器中:

public void start_Request(String uri, org.xml.sax.Attributes attrs) {
     // make sure to read attributes correctly
     System.err.println("Request, name="+ attrs.getValue(0);
   }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM