在Java中获取带有命名空间的XML节点

3

我将要翻译的XML如下:

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" 
         xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
         xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
         xmlns:ccts="urn:un:unece:uncefact:documentation:2"
         xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
         xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
         xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
         xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
         xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <ext:UBLExtensions>
        <ext:UBLExtension>
            <ext:ExtensionContent>
                <!-- SOME CODE HERE -->
            </ext:ExtensionContent>
        </ext:UBLExtension>
        <ext:UBLExtension>
            <ext:ExtensionContent>
                <!-- I WANT TO GET THIS NODE -->
            </ext:ExtensionContent>
        </ext:UBLExtension>
    </ext:UBLExtensions>

我该如何获取这个节点?我尝试过
Document doc = dbf.newDocumentBuilder().parse(new FileInputStream(PATH_TO_MY_XML));
NodeList nodes = doc.getDocumentElement().getElementsByTagNameNS("*", "UBLExtension");

但它返回一个空数组。我该怎么办?


非常感谢。这是回复。你能回答并标记为已回答吗?(对我的英语很抱歉) - Giancarlo Ventura
3个回答

5

A - 演示代码

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class GetXMLNodeInJavaDemo {

    public static void main(String[] args) {

        try {
            File fXmlFile = new File("sampleFile.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();

            dbFactory.setNamespaceAware(true);

            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);

            doc.getDocumentElement().normalize();

            printByElementTagname(doc);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void printByElementTagname(Document doc) {
        NodeList nodes = doc.getDocumentElement().getElementsByTagNameNS("*", "UBLExtension");
        Node node;
        for(int i = 0; i < nodes.getLength(); i++) {
            node = nodes.item(i);
            System.out.println(node.getNodeName() + " : " + node.getTextContent().trim());
        }
    }

}

B - 样本文件: sampleFile.xml

<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" 
         xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
         xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
         xmlns:ccts="urn:un:unece:uncefact:documentation:2"
         xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
         xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
         xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2"
         xmlns:sac="urn:sunat:names:specification:ubl:peru:schema:xsd:SunatAggregateComponents-1"
         xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <ext:UBLExtensions>
        <ext:UBLExtension>
            <ext:ExtensionContent>
                Some Code
            </ext:ExtensionContent>
        </ext:UBLExtension>
        <ext:UBLExtension>
            <ext:ExtensionContent>
                What you want
            </ext:ExtensionContent>
        </ext:UBLExtension>
    </ext:UBLExtensions>
</Invoice>

C - 样例输出

ext:UBLExtension : Some Code
ext:UBLExtension : What you want

1
@Giancarlo Ventura Granados 如果这真的有帮助,我会更开心的,你可以点个赞 :) - Levent Divilioglu
我仍然无法为您的回复点赞,我只有13个声望点。 - Giancarlo Ventura
@Giancarlo Ventura 没问题,我不知道有这样的机制,对不起。欢迎来到Stack Overflow :) - Levent Divilioglu
1
@Giancarlo Ventura Granados 我注意到了 :D - Levent Divilioglu

2

您需要确保XML解析器具有命名空间意识。

您还应该确保关闭FileInputStream,最好使用try-with-resources。

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

Document doc;
try (InputStream xmlStream = new FileInputStream(PATH_TO_MY_XML)) {
    doc = dbf.newDocumentBuilder().parse(xmlStream);
}
NodeList nodes = doc.getDocumentElement().getElementsByTagNameNS("*", "UBLExtension");

非常感谢,这是回复。 我仍然无法给你积分,但我已经标记为正确。 - Giancarlo Ventura
最好实际指定命名空间,而不是使用通配符。定义一个 static final String 常量,例如 EXT_NS = "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2",并在 "*" 的位置使用它。 - Andreas

1
你可以尝试使用xpath来处理。
public static NodeList getNodesWithXPath(Node aNode, String aXPath) {
    try {
        XPathFactory xPathfactory = XPathFactory.newInstance();
        XPath xpath = xPathfactory.newXPath();
        XPathExpression xPathExpression = xpath.compile(aXPath);
        return (NodeList) xPathExpression.evaluate(aNode, XPathConstants.NODESET);
    } catch (XPathExpressionException e) {
        // ignore
    } catch (NullPointerException e) {
        // ignore
    }
    return null;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接