【问题标题】:parse xml using xpath and get nested childs使用 xpath 解析 xml 并获取嵌套的子项
【发布时间】:2017-07-12 22:11:09
【问题描述】:

所以,我有一个看起来像这样的 XML 结构。

<root xmlns:foo="http://www.foo.org/" xmlns:bar="http://www.bar.org">
    <actors>
        <actorUID>1w2e3r</actorUID>
        <actor id="1">
            <name>Christian Bale</name>
            <age>40</age>
        </actor>
        <actor id="2">
            <name>LiamNeeson</name>
            <age>45</age>
        </actor>
        <actor id="3">
            <name>Michael</name>
            <age>60</age>
        </actor>
    </actors>
    <foo:singers>
        <foo:singer id="4">
            <name>Michael</name>
            <age>60</age>
        </foo:singer>
        <foo:singer id="5">
            <name>Michael</name>
            <age>60</age>
        </foo:singer>
        <foo:singer id="6">
            <name>Michael</name>
            <age>60</age>
        </foo:singer>
    </foo:singers>
</root>

我需要解析这个json并将actorUID、actor.name、actor.age、foo:singers.name、foo:singers.age的元素保存到数据库中。

我试过这个:

try {
                DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                DocumentBuilder db = dbf.newDocumentBuilder();
                InputSource is = new InputSource();
                is.setCharacterStream(new StringReader(stops));
                Document doc = db.parse(is);
                XPathFactory xPathfactory = XPathFactory.newInstance();
                XPath xpath = xPathfactory.newXPath();
                XPathExpression expr = xpath.compile("/root/actors");
                NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

                for (int i = 0; i < nl.getLength(); i++) {
                    Element element = (Element) nl.item(i);
                    System.out.println(element.getElementsByTagName("actorsUID")
                            .item(0)
                            .getTextContent());
                    System.out.println(element.getElementsByTagName("actor")
                            .item(0)
                            .getTextContent());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

我得到这个后如何获得演员姓名 - element.getElementsByTagName("actor") ?

我不想只获取 name 元素,因为如果我必须将另一个子元素添加到演员,并且如果它有 actor.name,那么它会中断。

【问题讨论】:

    标签: java xml xpath


    【解决方案1】:

    实际上我建议实现一个 SAX 解析器。但是如果你想使用 xpath,有两点需要注意:

    • DocumentBuilderFactory 必须知道命名空间

    • xpath 必须使用 NamespaceContext。

    您可以将它们设置为:

    dbf.setNamespaceAware(true);
    
    javax.xml.namespace.NamespaceContext ns = new javax.xml.namespace.NamespaceContext()
    {
    
        @Override
        public String getNamespaceURI(String prefix) 
        {
            if ( "foo".equals( prefix ) )
            {
                return "http://www.foo.org/";
            }
            else if ( "bar".equals( prefix ) )
            {
                return "http://www.bar.org/";
            }
            else if ( "xml".equals( prefix ) )
            {
                return javax.xml.XMLConstants.XML_NS_URI;
            }
    
            return javax.xml.XMLConstants.NULL_NS_URI;
    
        }
    
        @Override
        public String getPrefix(String namespaceURI) {
            return null;
        }
    
        @Override
        public Iterator<?> getPrefixes(String namespaceURI) {
            return null;
        }
    
    };
    
    xpath.setNamespaceContext(ns);
    

    然后要获取nameage 或任何其他子节点,您可以使用以下代码,基本上您会获取actor 的子节点并打印节点名称、文本。

    for (int i = 0; i < nl.getLength(); i++) 
    {
         Element element = (Element) nl.item(i);
         NodeList uids = element.getElementsByTagName("actorUID");
         for ( int j = 0; j < uids.getLength(); j++ )
         {
            System.out.println( "Actor UID : " + uids.item(j).getTextContent());
         }
         NodeList actors = element.getElementsByTagName("actor");
         for ( int j = 0; j < actors.getLength(); j++ )
         {
            NodeList cNodes = actors.item(j).getChildNodes();
            for ( int k = 0; k < cNodes.getLength(); k++ )
            {
                Node node = cNodes.item(k);
                if ( node.getNodeType() == Node.ELEMENT_NODE )
                {
                    System.out.println( cNodes.item(k).getNodeName() + " : " + cNodes.item(k).getTextContent() );
                }
    
            }
         }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      • 2017-10-10
      相关资源
      最近更新 更多