XML 获取所有具有相同名称的节点 [英] XML get all nodes with the same name

查看:107
本文介绍了XML 获取所有具有相同名称的节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有如下所示的 xml 文档:

I have xml documents that look like this:

<?xml version="1.0"?>
<root>
    <success>true</success>
    <note>
        <note_id>32219</note_id>
        <the_date>1336763490</the_date>
        <member_id>108649</member_id>
        <area>6</area>
        <note>Note 123123123</note>
    </note>
    <note>
        <note_id>33734</note_id>
        <the_date>1339003652</the_date>
        <member_id>108649</member_id>
        <area>1</area>
        <note>This is another note.</note>
    </note>
    <note>
        <note_id>49617</note_id>
        <the_date>1343050791</the_date>
        <member_id>108649</member_id>
        <area>1</area>
        <note>this is a 3rd note.</note>
    </note>
</root>

我想获取该文档,并获取所有 标记并将它们转换为字符串,然后将它们传递给我的 XML 类并将 XML 类放入一个数组中列表.我希望这是有道理的.所以这是我试图用来获取所有 <note> 标签的方法.

I would like to take that document, and get all of the <note> tags and convert them to a string, then pass them to my XML class and place the XML class into an array list. I hope that makes sense. So Here is the method that I am trying to use to get all of the <note> tags.

public ArrayList<XML> getNodes(String root, String name){
    ArrayList<XML> elList = new ArrayList<>();
    NodeList nodes = doc.getElementsByTagName(root);
    for(int i = 0; i < nodes.getLength(); i++){
        Element element = (Element)nodes.item(i);
        NodeList nl = element.getElementsByTagName(name);
        for(int c = 0; c < nl.getLength(); c++){
            Element e = (Element)nl.item(c);
            String xmlStr = this.nodeToString(e);
            XML xml = new XML();
            xml.parse(xmlStr);
            elList.add(xml);
        }
    }
    return elList;
}

private String nodeToString(Node node){
    StringWriter sw = new StringWriter();
    try{
        Transformer t = TransformerFactory.newInstance().newTransformer();
        t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        t.transform(new DOMSource(node), new StreamResult(sw));
    }catch(TransformerException te){
        System.out.println("nodeToString Transformer Exception");
    }
    return sw.toString();
}

所以,我的问题是,如何将每个 标记作为字符串获取?使用我现在拥有的代码,我返回的是 null for String xmlStr = e.getNodeValue();.

So, my question is, how can I get each <note> tag as a string? With the code I have now all I get back is null for String xmlStr = e.getNodeValue();.

编辑
我编辑了我的主要代码,这似乎有效.

Edit
I edited my main code, this seems to work.

推荐答案

澄清后更新

您可以使用 XPath 找到所有 元素.

You can find all the <note> elements using XPath.

这将允许您简单地隔离每个节点.然后,您可以根据找到的节点创建一个新文档并将其转换回字符串

This will allow you to isolate each node simply. You can then create a new document, based on the found nodes and transform it back to string

public class TestXML01 {

    public static void main(String[] args) {

        String xml = "<?xml version=\"1.0\"?>";
        xml += "<root>";
        xml += "<success>true</success>";
        xml += "<note>";
        xml += "<note_id>32219</note_id>";
        xml += "<the_date>1336763490</the_date>";
        xml += "<member_id>108649</member_id>";
        xml += "<area>6</area>";
        xml += "<note>Note 123123123</note>";
        xml += "</note>";
        xml += "<note>";
        xml += "<note_id>33734</note_id>";
        xml += "<the_date>1339003652</the_date>";
        xml += "<member_id>108649</member_id>";
        xml += "<area>1</area>";
        xml += "<note>This is another note.</note>";
        xml += "</note>";
        xml += "<note>";
        xml += "<note_id>49617</note_id>";
        xml += "<the_date>1343050791</the_date>";
        xml += "<member_id>108649</member_id>";
        xml += "<area>1</area>";
        xml += "<note>this is a 3rd note.</note>";
        xml += "</note>";
        xml += "</root>";

        ByteArrayInputStream bais = null;

        try {
            bais = new ByteArrayInputStream(xml.getBytes());
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(false);
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document xmlDoc = builder.parse(bais);

            Node root = xmlDoc.getDocumentElement();

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

            XPathExpression xExpress = xPath.compile("/root/note");
            NodeList nodes = (NodeList) xExpress.evaluate(root, XPathConstants.NODESET);

            System.out.println("Found " + nodes.getLength() + " note nodes");

            for (int index = 0; index < nodes.getLength(); index++) {
                Node node = nodes.item(index);
                Document childDoc = builder.newDocument();
                childDoc.adoptNode(node);
                childDoc.appendChild(node);
                System.out.println(toString(childDoc));
            }

        } catch (Exception exp) {
            exp.printStackTrace();
        } finally {
            try {
                bais.close();
            } catch (Exception e) {
            }
        }
    }

    public static String toString(Document doc) {

        String sValue = null;

        ByteArrayOutputStream baos = null;
        OutputStreamWriter osw = null;

        try {
            baos = new ByteArrayOutputStream();
            osw = new OutputStreamWriter(baos);

            Transformer tf = TransformerFactory.newInstance().newTransformer();
            tf.setOutputProperty(OutputKeys.INDENT, "yes");
            tf.setOutputProperty(OutputKeys.METHOD, "xml");
            tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

            DOMSource domSource = new DOMSource(doc);
            StreamResult sr = new StreamResult(osw);
            tf.transform(domSource, sr);

            osw.flush();
            baos.flush();
            sValue = new String(baos.toByteArray());
        } catch (Exception exp) {
            exp.printStackTrace();
        } finally {
            try {
                osw.close();
            } catch (Exception exp) {
            }
            try {
                baos.close();
            } catch (Exception exp) {
            }
        }
        return sValue;
    }
}

现在输出...

Found 3 note nodes
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<note>
    <note_id>32219</note_id>
    <the_date>1336763490</the_date>
    <member_id>108649</member_id>
    <area>6</area>
    <note>Note 123123123</note>
</note>

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<note>
    <note_id>33734</note_id>
    <the_date>1339003652</the_date>
    <member_id>108649</member_id>
    <area>1</area>
    <note>This is another note.</note>
</note>

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<note>
    <note_id>49617</note_id>
    <the_date>1343050791</the_date>
    <member_id>108649</member_id>
    <area>1</area>
    <note>this is a 3rd note.</note>
</note>

这篇关于XML 获取所有具有相同名称的节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆