java - 如何使用 Xpath java 解析带有命名空间的 xml

标签 java xml xpath

我有一个具有命名空间但没有前缀的 xml。我有 xpath,但带有从 Schematron 生成的前缀。我想使用带有前缀的 xpath 从该 xml 中获取元素详细信息。

这是我的 XML

<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://foo" type="abc" id="ad">
    <title>Document Title</title>
    <body>
        <p>
            <t>Document Body</t>
        </p>
        <p>
            <t>Document Body</t>
        </p>
        <p>
            <t>Document Body</t>
        </p>
    </body>
</section>

这是java代码

package com;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class XPathTest {
    public static void main(String[] args) {
        File inputFile = new File("files/my_xml.xml");
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder;
        try {
            dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(inputFile);
            doc.getDocumentElement().normalize();

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

            HashMap<String, String> prefMap = new HashMap<String, String>() {
                {
                    put("q", "http://foo");
                }
            };
            SmartContentNameSpaceContext namespaces = new SmartContentNameSpaceContext(prefMap);
            xPath.setNamespaceContext(namespaces);

            String expression = "//q:section[1]";
            NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET);

            for (int i = 0; i < nodeList.getLength(); i++) {
                Node node = nodeList.item(i);

                System.out.println(node.getAttributes().item(0));
                System.out.println("current element : " + node.getNodeName());
            }
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (XPathExpressionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

我读到了 NameSpaceContext 接口(interface),所以我尝试过

HashMap<String, String> prefMap = new HashMap<String, String>() {
                {
                    put("q", "foo");
                }
            };
MyNameSpaceContext namespaces = new MyNameSpaceContext(prefMap);
xPath.setNamespaceContext(namespaces);

这是 MyNameSpaceContext

package com;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.xml.namespace.NamespaceContext;

public class MyNameSpaceContext implements NamespaceContext {

    private final Map<String, String> PREF_MAP = new HashMap<String, String>();

    public SmartContentNameSpaceContext(final Map<String, String> prefMap) {
        PREF_MAP.putAll(prefMap);
    }

    @Override
    public String getNamespaceURI(String prefix) {
        return PREF_MAP.get(prefix);
    }

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

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

}

但这不起作用?

最佳答案

您需要确保使用

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);

如果您想在 DOM 树上使用 XPath。我没有进一步寻找其他问题。

关于java - 如何使用 Xpath java 解析带有命名空间的 xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41588950/

相关文章:

javascript - 在 XSL 转换期间在字符串中保留注释符号

xsd - DTD 或 XML 架构。哪一个更好?

jquery - 内部循环(附加另一个循环)

c# - 如何使用此示例的 htmlagilitypack 从 HTML 中提取文本?

java - 无法切换到 Selenium 中的框架,并在下面的描述中给出了详细信息

html - 如何使用 Xpath 定位此元素?

java - Spring 问题 : Error creating beans and Injection of autowired dependencies failed

java - 窗口是在屏幕外绘制的java程序

java - 单元测试 - junit 和 Mockito。测试 addNewAccount 到数据库,如果我需要删除/删除帐户

java - Spring 4 @RequestMapping - 消耗 vs header ?