Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用根元素语法中的名称空间前缀解析XML-Java_Java_Xml_Xpath_Xml Namespaces - Fatal编程技术网

使用根元素语法中的名称空间前缀解析XML-Java

使用根元素语法中的名称空间前缀解析XML-Java,java,xml,xpath,xml-namespaces,Java,Xml,Xpath,Xml Namespaces,我有一个XML格式: <?xml version="1.0" encoding="UTF-8"?> <semseg:Envelope xmlns:semseg="http://a-random-URL" xmlns="http://another-random-URL"> <semseg:subject>Subject</semseg:subject> <semseg:Sender> <semseg

我有一个
XML
格式:

<?xml version="1.0" encoding="UTF-8"?>
<semseg:Envelope xmlns:semseg="http://a-random-URL" xmlns="http://another-random-URL">
    <semseg:subject>Subject</semseg:subject>
    <semseg:Sender>
        <semseg:name>Me</semseg:name>
    </semseg:Sender>
    <Triangle>
        <Triangle time='2017-11-29'>
            <Triangle key='a' value='b'/>
            <Triangle key='c' value='d'/>
            <Triangle key='e' value='f'/>
            <Triangle key='g' value='h'/>
        </Triangle>
    </Triangle>
</semseg:Envelope>
不幸的是,由于没有选择任何元素,我尝试了许多可能的XPath组合。然而,使用在线
XPath
检查器和相同的
XML
文件测试相同的
XPath
,可以得到我想要的结果。它甚至可以使用XPath之类的工具进行属性检索

/semseg:Envelope/Triangle/Triangle/@time
似乎名称空间前缀有问题。解析
XML
s而不使用任何名称空间前缀,对于
XPath

很好,这对我来说很有用


/\*[local-name()='Envelope']/\*[local-name()='Triangle']/\*[local-name()='Triangle']/@time

您的XML输入实际上有两个名称

默认名称空间 第一个是默认值,声明如下:

<semseg:Envelope ... xmlns="http://another-random-URL" ...
<semseg:Envelope xmlns:semseg="http://a-random-URL" ...
这是有效的:

XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
xPath.setNamespaceContext(new NamespaceContext() {
    @Override
    public String getNamespaceURI(String prefix) {
        if ("main".equals(prefix)) {
            return "http://a-random-URL";
        }
        if ("secondary".equals(prefix)) {
            return "http://another-random-URL";
        }
        return null;
    }
    @Override
    public String getPrefix(String namespaceURI) {
        // This should be implemented but I'm lazy and this sample works without it
        return null;
    }

    @Override
    public Iterator getPrefixes(String namespaceURI) {
        // This should be implemented but I'm lazy and this sample works without it
        return null;
    }
});
XPathExpression xpr = xPath.compile("/main:Envelope/secondary:Triangle");
NodeList nodes = (NodeList)xpr.evaluate(doc, XPathConstants.NODESET);
System.out.println(nodes.getLength());
产出:

1

在这里,我实现了一个非常愚蠢的名称空间上下文,但是如果您有Spring框架、CXF、guava(我想)或其他reach框架,您通常会有类似于
SimpleNamespaceContext
MapBasedNamespaceContext
的东西,这可能是更好的选择。

您看过了吗?我想您可以尝试一下,“//三角形[不是(@*)]“作为你的xpath@reflexdemon这行不通unfortunately@GPI我不能真正使用名称空间上下文,因为前缀只适用于XML中的某些元素。你可以看到,
Envelope
确实有这样一个前缀,但
Triangle
没有。这确实有效,但我一直在寻找更优雅和简洁的答案,这就是为什么我对它进行了投票,但没有将其标记为可接受的答案。不过非常感谢!
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
xPath.setNamespaceContext(new NamespaceContext() {
    @Override
    public String getNamespaceURI(String prefix) {
        if ("main".equals(prefix)) {
            return "http://a-random-URL";
        }
        if ("secondary".equals(prefix)) {
            return "http://another-random-URL";
        }
        return null;
    }
    @Override
    public String getPrefix(String namespaceURI) {
        // This should be implemented but I'm lazy and this sample works without it
        return null;
    }

    @Override
    public Iterator getPrefixes(String namespaceURI) {
        // This should be implemented but I'm lazy and this sample works without it
        return null;
    }
});
XPathExpression xpr = xPath.compile("/main:Envelope/secondary:Triangle");
NodeList nodes = (NodeList)xpr.evaluate(doc, XPathConstants.NODESET);
System.out.println(nodes.getLength());
1