简体   繁体   中英

Read Inner XML of a XML Element

I was looking thru StackOverflow but i can't find best answer. I need to read XML file in JAVA. My XML file looks like below: `

<?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>

Is there a possiblity to read in Java elements between <server01> and <server02> , excluding rest of file? Or I need to use different tags? I found method how to read parentnodes:

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());
    }
}

I am able to read all departments tags and save them to array:

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]);
}

So, again, is there a possibility to read elements of parent node only? Elements of SERVER01 only?

XPath is what you want. For all intents and purposes, you can think of xpath as you would sql, only it is for xml documents instead of databases. Here is a simple example using Java (keep in mind xpath is a standard and not specific to java, so you can find many ways of doing this in pretty much any popular language):

    // 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() );
        }
    }

Is there is a possibility to avoid this?

Yes just change XPath expression an receive only nodes you need.

// 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() );
    }
}

You must receive the next output:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM