21

I have an xml which looks like this:

{ <xml><ep><source type="xml">...</source><source type="text">..</source></ep></xml>}

Here I want to retrieve the value of "source type" where type is an attribute.

I tried the following, which didn't work:

DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
try {
    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document dDoc = builder.parse("D:/workspace1/ereader/src/main/webapp/configurations/config.xml");
    System.out.println(dDoc);
    XPath xPath = XPathFactory.newInstance().newXPath();
    Node node = (Node) xPath.evaluate("//xml/source/@type/text()", dDoc, XPathConstants.NODE);
    System.out.println(node);
} catch (Exception e) {
    e.printStackTrace();

This also didn't work:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader("config.xml"));
Document doc = builder.parse(is);

NodeList nodeList = doc.getElementsByTagName("source");

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

    if (node.hasAttributes()) {
        Attr attr = (Attr) node.getAttributes().getNamedItem("type");
        if (attr != null) {
            String attribute = attr.getValue();
            System.out.println("attribute: " + attribute);
        }
    }
}
starball
  • 20,030
  • 7
  • 43
  • 238
Priya
  • 469
  • 3
  • 6
  • 14
  • Have u tried using VTD-XML http://vtd-xml.sourceforge.net/ It is faster and more memory efficient. – Rosdi Kasim Aug 09 '12 at 04:38
  • hi Rosdi, No i've n't tried, anyways ATR's code works fine, and my snippet too:) thanks for ur kind response – Priya Aug 09 '12 at 05:04

7 Answers7

33

Since your question is more generic so try to implement it with XML Parsers available in Java .If you need it in specific to parsers, update your code here what you have tried yet

<?xml version="1.0" encoding="UTF-8"?>
<ep>
    <source type="xml">TEST</source>
    <source type="text"></source>
</ep>
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("uri to xmlfile");
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("//ep/source[@type]");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);

for (int i = 0; i < nl.getLength(); i++)
{
    Node currentItem = nl.item(i);
    String key = currentItem.getAttributes().getNamedItem("type").getNodeValue();
    System.out.println(key);
}
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
thar45
  • 3,518
  • 4
  • 31
  • 48
  • 1
    i've tried the above snippet and i dono to proceed with, kindly help me!! i need to get the value "xml" and "text" alone. that's my requirement. – Priya Aug 08 '12 at 11:22
  • 1
    ATR, Its actually //xml/ep/source/@type i've edited few statements in ur code.. and it works fine.. thanks :) – Priya Aug 09 '12 at 05:07
  • Is there a way i can get the value in between the tags, in above sample, TEST, how can i read TEST – Srikanth Josyula Nov 16 '20 at 06:34
4

try something like this :

    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document dDoc = builder.parse("d://utf8test.xml");

    XPath xPath = XPathFactory.newInstance().newXPath();
    NodeList nodes = (NodeList) xPath.evaluate("//xml/ep/source/@type", dDoc, XPathConstants.NODESET);
    for (int i = 0; i < nodes.getLength(); i++) {
        Node node = nodes.item(i);
        System.out.println(node.getTextContent());
    }

please note the changes :

  • we ask for a nodeset (XPathConstants.NODESET) and not only for a single node.
  • the xpath is now //xml/ep/source/@type and not //xml/source/@type/text()

PS: can you add the tag java to your question ? thanks.

mabroukb
  • 691
  • 4
  • 11
2

I'm happy that this snippet works fine:

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(new File("config.xml"));
NodeList nodeList = document.getElementsByTagName("source");
for(int x=0,size= nodeList.getLength(); x<size; x++) {
    System.out.println(nodeList.item(x).getAttributes().getNamedItem("type").getNodeValue());
} 
nhahtdh
  • 55,989
  • 15
  • 126
  • 162
Priya
  • 469
  • 3
  • 6
  • 14
1

use

document.getElementsByTagName(" * ");

to get all XML elements from within an XML file, this does however return repeating attributes

example:

NodeList list = doc.getElementsByTagName("*");


System.out.println("XML Elements: ");

        for (int i=0; i<list.getLength(); i++) {

            Element element = (Element)list.item(i);
            System.out.println(element.getNodeName());
        }
Dan Pickard
  • 453
  • 6
  • 14
1

Below is the code to do it in VTD-XML

import com.ximpleware.*;

public class queryAttr{
     public static void main(String[] s) throws VTDException{
         VTDGen vg= new VTDGen();
         if (!vg.parseFile("input.xml", false))
            return false;
         VTDNav vn = vg.getNav();
         AutoPilot ap = new AutoPilot(vn);
         ap.selectXPath("//xml/ep/source/@type");
         int i=0;
         while((i = ap.evalXPath())!=-1){
               system.out.println(" attr val ===>"+ vn.toString(i+1));

         }
     }
}
vtd-xml-author
  • 3,319
  • 4
  • 22
  • 30
0
public static void main(String[] args) throws IOException {
    String filePath = "/Users/myXml/VH181.xml";
    File xmlFile = new File(filePath);
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder;
    try {
        dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(xmlFile);
        doc.getDocumentElement().normalize();
        printElement(doc);
        System.out.println("XML file updated successfully");
    } catch (SAXException | ParserConfigurationException e1) {
        e1.printStackTrace();
    }
}
private static void printElement(Document someNode) {
    NodeList nodeList = someNode.getElementsByTagName("choiceInteraction");
    for(int z=0,size= nodeList.getLength();z<size; z++) {
            String Value = nodeList.item(z).getAttributes().getNamedItem("id").getNodeValue();
            System.out.println("Choice Interaction Id:"+Value);
        }
    }

we Can try this code using method

Tamil veera Cholan
  • 512
  • 1
  • 8
  • 21
0

Below is the utility method I have written to get value of any node from the root Document object and a given XPATH.

public String getValue(Document doc, String xPath) throws Exception {
   XPathFactory factory = XPathFactory.newInstance();
   XPath path = factory.newXPath();
   XPathExpression expression = path.compile(xPath);
   Node node = (Node) expression.evaluate(doc,XPathConstants.NODE);
   return node.getFirstChild().getNodeValue();
}

All the libraries are from java.xml.xpath and org.w3c.dom.

Now all you need the root document element and correct Path. For your example if will /ep/source/@type

So, basically XPAth is to navigate till the element you are after and followed by /@attributeName you are interested in.

Please node /ep/source@type won't work. (I wasted 30 min troubleshooting this).

Sanjay Bharwani
  • 3,317
  • 34
  • 31