读取 XML 元素的内部 XML

Posted

技术标签:

【中文标题】读取 XML 元素的内部 XML【英文标题】:Read Inner XML of a XML Element 【发布时间】:2013-10-06 17:28:12 【问题描述】:

我正在查看 ***,但找不到最佳答案。我需要在 JAVA 中读取 XML 文件。我的 XML 文件如下所示:`

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<server>
    <server01>
       <department>A1</department>
       <department>A2</department> 
    </server01>
    <server02>
       <department>A1</department>
       <department>A2</department> 
    </server02>
</server>

是否可以读取&lt;server01&gt;&lt;server02&gt; 之间的Java 元素,不包括文件的其余部分?或者我需要使用不同的标签?我找到了如何读取父节点的方法:

NodeList serversNames = xmlD.getDocumentElement().getChildNodes();

for (int i = 0; i < serversNames.getLength(); i++) 
    Node node = serversNames.item(i);
    if (node instanceof Element) 
        Element childElement = (Element) node;
        System.out.println("tag name: " + childElement.getTagName());
    

我能够读取所有部门标签并将它们保存到数组中:

NodeList serverName = xmlD.getElementsByTagName("department");

serversList = new String[serverName.getLength()];

System.out.println("zasieg: " + serverName.getLength());

for (int temp = 0; temp < serverName.getLength(); temp++) 
    Element shareName = null;

    shareName = (Element) serverName.item(temp);

    serversList[temp] = shareName.getTextContent();
    System.out.println(temp + " - " + serversList[temp]);

那么,是否有可能只读取父节点的元素?仅 SERVER01 的元素?

【问题讨论】:

你是说你在读完的内容后要停止阅读文档,而不是读入的内容吗?我认为您需要在程序中定义该逻辑,它不会真正成为任何 XML 解析器的一部分。 不清楚您要做什么或问题是什么。你不能只使用 XPath 或等效的吗?如果你使用事件驱动的解析器,你可以随时停止,如果它真的值得的话。 您可以使用xstream将XML转为对象,将对象转为XML,非常简单的方法将XML转为对象,将对象转为XML。 这是一个有用的参考:viralpatel.net/blogs/java-xml-xpath-tutorial-parse-xml @MattN:不正确。解析 XML 标记有 2 种方法:DOM(将整个文件读入树形数据结构)和 SAX(在文件中流式传输并处理在解析过程中遇到的标签)。听起来像提前终止的基于 SAX 的 xml 解析方法会很好地满足 OP 的需求。见***.com/questions/6828703/… 【参考方案1】:

XPath 是你想要的。出于所有意图和目的,您可以将 xpath 视为 sql,只是它用于 xml 文档而不是数据库。这是一个使用 Java 的简单示例(请记住,xpath 是一个标准,并非特定于 java,因此您可以在几乎任何流行语言中找到许多方法):

    // Load document
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse( new FileInputStream( "/tmp/xml" ) );

    // Create XPath expression
    XPathFactory xPathfactory = XPathFactory.newInstance();
    XPath xpath = xPathfactory.newXPath();
    XPathExpression expr = xpath.compile( "//server01" );

    // Find node 'server01'
    Node node = (Node) expr.evaluate( doc, XPathConstants.NODE );
    if( node == null ) 
        System.out.println( "Node not found" );
        System.exit( 0 );
    

    // Extract departments
    Element server01 = (Element) node;
    for( int k = 0 ; k < server01.getChildNodes().getLength() ; k++ ) 
        Node childNode = server01.getChildNodes().item( k );
        // Check if current node is a department node
        if( "department".equals( childNode.getNodeName() ) ) 
            System.out.println( childNode.getNodeName() + ": " + childNode.getTextContent().trim() );
        
    

有没有可能避免这种情况?

是的,只需将 XPath 表达式更改为只接收您需要的节点。

// Load document
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse( new FileInputStream( "/tmp/xml" ) );

// Create XPath expression
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile( "//server01/department" );

// Find nodes 'department' under node 'server01'
NodeList node = (NodeList) expr.evaluate( doc, XPathConstants.NODESET );

// Extract departments
for( int k = 0 ; k < node.getLength() ; k++ ) 
    Node childNode = node.item( k );
    // Check if current node is a department node
    if( "department".equals( childNode.getNodeName() ) ) 
        System.out.println( "[" + k + "] " + childNode.getNodeName() + ": " + childNode.getTextContent().trim() );
    

你必须收到下一个输出:

[0] department: A1
[1] department: A2

【讨论】:

为了确保我不会因为我的编辑而从你那里拿分,我已经删除了我的答案并给了你一个赞成票,因为我们基本上有相同的答案。 嗨。这是第一个简单的解决方案。我并不感到惊讶,我并不孤单:) 谢谢!这是非常有帮助的:)。但是,有一件事,就是不明白。程序的输出是:null 1 - AP null 3 - AR null 5 - GL null 7 - CS null 9 - CL 为什么这样算?不是 1,2,3... 而是只有奇数? 你改变了原来的例子吗?我已经测试过了,输出显示正确的行:department: A1 您在奇数迭代中收到 'department' 节点,因为标签之间存在带有 '\n' 内容的 '#text' 节点。

以上是关于读取 XML 元素的内部 XML的主要内容,如果未能解决你的问题,请参考以下文章

Java / Android - 读取、操作 XML 文件并将其保存到内部存储

java如何读取xml节点元素值?

从 XML 文件中读取特定的 XML 元素

从 xml 读取特定元素

将 Xml 元素读取到 Excel

读取 XML 元素时出现异常