簡體   English   中英

從復雜的空元素解析XML屬性

[英]Parsing XML attributes from Complex Empty Elements

我有以下格式的xml文件,其中包含一些Complex Empty Elements (元素不包含內容,僅包含屬性)。

<items>
    <item id="0" name="a" />
    <item id="1" name="b" />
</items>

我不敢解析它們的屬性。 到目前為止,這是我所做的:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(inputStream);
Element itemsElement = document.getDocumentElement();
if (itemsElement.getTagName().equals(TAG_ITEMS)) {
    NodeList nodeList = itemsElement.getChildNodes();
    for (int i = 0; i < nodeList.getLength(); i++) {
        // process each item node
        Node node = nodeList.item(i);
        if (node.getNodeType() == Node.TEXT_NODE) { // Is this the right way?
            Text text = (Text) node;
            // Do stuff with attributes
        }
    }
}

我無法將這些Text節點強制轉換為Element節點並獲取屬性,無法使用NamedNodeMap attributes.getLength() getAttributes -NPE從節點獲取屬性,也無法將其NamedNodeMap attributes.getLength()Text並獲取屬性。 如何解析屬性?

您對items內部節點的文本上下文不感興趣,但對節點item的屬性感興趣。 您可以按照以下步驟操作:

//process each item node
Node node = nodeList.item(i);
if (node.getNodeName().equals("item")) {
    NamedNodeMap attributes = node.getAttributes();
    System.out.printf("id=%s, name=%s%n", 
            attributes.getNamedItem("id").getTextContent(),
            attributes.getNamedItem("name").getTextContent());
}

這將打印:

id=0, name=a
id=1, name=b

假設您想要獲取節點的個別屬性,則需要滿足以下兩種條件之一(或根據您的需要而定)...

您需要測試當前節點是否為ELEMENT_NODE或當前節點的名稱是否等於item (假設所有節點名稱均相同),例如...

import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

public class Test {

    public static final String TAG_ITEMS = "items";

    public static void main(String[] args) {
        try (InputStream is = Test.class.getResourceAsStream("/Test.xml")) {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(is);
            Element itemsElement = document.getDocumentElement();
            if (itemsElement.getTagName().equals(TAG_ITEMS)) {
                NodeList nodeList = itemsElement.getChildNodes();
                for (int i = 0; i < nodeList.getLength(); i++) {
                    Node node = nodeList.item(i);
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        NamedNodeMap attributes = node.getAttributes();
                        Node idAtt = attributes.getNamedItem("id");
                        Node nameAtt = attributes.getNamedItem("name");
                        System.out.println("id = " + idAtt.getNodeValue());
                        System.out.println("name = " + nameAtt.getNodeValue());
                    }
                }
            }
        } catch (Exception exp) {
            exp.printStackTrace();
        }
    }

}

將輸出...

id = 0
name = a
id = 1
name = b

使用XPath可以大大減少所有這些情況,例如,如果所有item節點都具有相同的名稱,那么您可以使用

/items/item

作為查詢。 如果節點名稱不同,但屬性相同,則可以使用

/items/*[@id]

它將列出具有id屬性的items下的所有節點,或者

/items/*[@name]

它將列出具有name屬性的items下的所有節點...

import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class Test {

    public static void main(String[] args) {
        try (InputStream is = Test.class.getResourceAsStream("/Test.xml")) {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse(is);

            XPath xpath = XPathFactory.newInstance().newXPath();
            XPathExpression expression = xpath.compile("/items/item");
            NodeList nodes = (NodeList) expression.evaluate(document, XPathConstants.NODESET);
            process(nodes);

            expression = xpath.compile("/items/*[@id]");
            nodes = (NodeList) expression.evaluate(document, XPathConstants.NODESET);
            process(nodes);

            expression = xpath.compile("/items/*[@name]");
            nodes = (NodeList) expression.evaluate(document, XPathConstants.NODESET);
            process(nodes);
        } catch (Exception exp) {
            exp.printStackTrace();
        }
    }

    protected static void process(NodeList nodes) {
        for (int index = 0; index < nodes.getLength(); index++) {
            Node item = nodes.item(index);
            NamedNodeMap attributes = item.getAttributes();
            Node idAtt = attributes.getNamedItem("id");
            Node nameAtt = attributes.getNamedItem("name");
            System.out.println("id = " + idAtt.getNodeValue() + "; name = " + nameAtt.getNodeValue());
        }
    }

}

暫無
暫無

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

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