【问题标题】:How to extract element value from an xml containing namespaces with xPath in Java?如何从包含 Java 中带有 xPath 的命名空间的 xml 中提取元素值?
【发布时间】:2018-08-29 07:53:01
【问题描述】:

环境:Windows 10、Eclipse、Java 1.5

目标: 我正在尝试使用 xPath 获取 xml 的元素文本值。 xml 包含各种命名空间。

问题:我总是得到一个空值。

我在 SO 上查看了一些线程,但没有任何效果。 xml绝对路径在浏览器上打开正常。

这就是我所拥有的:

//Initialize objects
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
builderFactory.setNamespaceAware(true);
builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(xmlFINAL);//File with absolute path
XPath xPath = (XPath) XPathFactory.newInstance().newXPath();  

//NamespaceContext used for xPath
NamespaceContext nsContext = new NamespaceContext (){
public String getNamespaceURI(String prefix) {
                 if (prefix == null) {            
                        throw new NullPointerException("Null prefix");
                  } else if ("ns2".equals(prefix)) {            
                        return "http://ns2";
                  }else{
                      return "http://ns1";
                  }

            }

            public String getPrefix(String namespaceURI) {
                return null;
            }

            public Iterator getPrefixes(String namespaceURI) {
                return null;
            }

        };
xPath.setNamespaceContext(nsContext);

This is a part of the Document content

测试xml(我的太大了):

<root_element xmlns="http://ns1" xmlns:ns2="http://ns2">
    <element1>
    ...
        <ns2:element2>
            <ns2:element3>I want this text</element3>
        </element2>
    ...
    </element1>
</root_element >

获取元素值(总是返回""):

String expression = "/root_element/element1/ns2:element2/ns2:element3/text()";
String valor = (String) xPath.compile(expression).evaluate(xmlDocument,XPathConstants.STRING);
//or
String valor = xPath.evaluate(expression, xmlDocument);

【问题讨论】:

    标签: java xml xpath namespaces


    【解决方案1】:

    这样工作得很好:

    public static void main(String[] args) throws Exception {
            XPathFactory xpf = XPathFactory.newInstance();
            XPath path = xpf.newXPath();
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
    
            File fileXML = new File("test.xml");
            Document xml = builder.parse(fileXML);
            Element dataset = xml.getDocumentElement();
    
            NamespaceContext ns = new NamespaceContext() {
                @Override
                public Iterator getPrefixes(String namespaceURI) {
                    return null;
                }
    
                @Override
                public String getPrefix(String namespaceURI) {
                    return namespaceURI.equalsIgnoreCase("http://ns1") ? "ns1" : namespaceURI.equalsIgnoreCase("http://ns2") ? "ns2" : "";
                }
    
                @Override
                public String getNamespaceURI(String prefix) {
                    return prefix.equalsIgnoreCase("ns1") ? "http://ns1" : prefix.equalsIgnoreCase("ns2") ? "http://ns2" : "";
                }
            };
    
            path.setNamespaceContext(ns);
    
            String exp1 = "/root_element";
            Node root = (Node) path.evaluate(exp1, dataset, XPathConstants.NODE);
            System.out.println(root.getNodeName() + " has " + root.getChildNodes().getLength() + " childrens (text included).");
    
            exp1 = "/root_element/element1";
            root = (Node) path.evaluate(exp1, dataset, XPathConstants.NODE);
            System.out.println(root.getNodeName() + " has " + root.getChildNodes().getLength() + " childrens (text included).");
    
            exp1 = "/root_element/element1/ns2:element2";
            root = (Node) path.evaluate(exp1, dataset, XPathConstants.NODE);
            System.out.println(root.getNodeName() + " has " + root.getChildNodes().getLength() + " childrens (text included).");
    
            exp1 = "/root_element//ns2:element3";
            root = (Node) path.evaluate(exp1, dataset, XPathConstants.NODE);
            System.out.println(root.getNodeName() + " has " + root.getChildNodes().getLength() + " childrens (text included).");
    
            exp1 = "/root_element//ns2:element3/text()";
            String text = (String) path.evaluate(exp1, dataset, XPathConstants.STRING);
            System.out.println("Text = " + text);
        }
    

    我使用的 XML:

    <root_element xmlns="" xmlns:ns1="http://ns1" xmlns:ns2="http://ns2">
        <element1>
            <ns2:element2>
                <ns2:element3>I want this text</ns2:element3>
            </ns2:element2>
        </element1>
    </root_element >
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-05
      • 2020-06-23
      • 2014-09-14
      • 2021-02-12
      • 2012-11-22
      • 2020-05-06
      • 2017-03-30
      相关资源
      最近更新 更多