Unable to read xml with namespace prefix using DOM parser

20,149

Solution 1

The W3C dom method for namespaced elements:

getElementsByTagNameNS

NodeList getElementsByTagNameNS(String namespaceURI,
                                String localName)

    Returns a NodeList of all the Elements with a given local name and namespace URI in document order.

    Parameters:
        namespaceURI - The namespace URI of the elements to match on. The special value "*" matches all namespaces.
        localName - The local name of the elements to match on. The special value "*" matches all local names. 
    Returns:
        A new NodeList object containing all the matched Elements.
    Since:
        DOM Level 2

IIRC earlier version of the W3C DOM had poor support for namespaces so I don't use it. However if you use the above with the full namespaceURI http://schemas.xmlsoap.org/soap/envelope/ it should work. The prefix is unimportant - it has no permanency outside the document it is used in.

so try:

System.out.println("Element :" + doc.getElementsByTagNameNS(
        "http://schemas.xmlsoap.org/soap/envelope/", "Token").item(0));

Solution 2

get the namespace first

docFactory.setNamespaceAware(true);
StringBuilder nameSpace = new StringBuilder(
                    doc.getDocumentElement().getPrefix() != null ? doc.getDocumentElement().getPrefix() + ":" : "");

then use nameSpace variable accrodingly

eg:

Node node= doc.getElementsByTagName(nameSpace + "Node1").item(0)
                    .getFirstChild();
Share:
20,149
Anand Jayabalan
Author by

Anand Jayabalan

Updated on July 23, 2022

Comments

  • Anand Jayabalan
    Anand Jayabalan almost 2 years

    This is the input XML:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
       <SOAP-ENV:Header/>
       <SOAP-ENV:Body>
          <ns2:SendResponse xmlns:ns2="http://mycompany.com/schema/">
             <ns2:SendResult>
                <ns2:Token>A00179-02</ns2:Token>
             </ns2:SendResult>
          </ns2:SendResponse>
       </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
    

    This the code that I'm using to read the XML (Variable xmlString contains the XML above):

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    DocumentBuilder db = dbf.newDocumentBuilder();
    InputSource is = new InputSource();
    is.setCharacterStream(new StringReader(xmlString));
    Document doc = db.parse(is);
    
    System.out.println("Element :" + doc.getElementsByTagName("Token").item(0));
    System.out.println("Element :" + doc.getElementsByTagName("ns2:Token").item(0));
    

    Output:

    Element :null
    Element :[ns2:Token: null]
    

    I'm able to read the element if I use "ns2:Token" as the tag name, but I don't want to use the prefix in my code as I'm not sure if it'll be the same or change in the future. Is there any way to read the xml element without hard-coding the namespace in the tag name?