XML attribute Parsing - java

When parsing the xml, I want to retrieve the token value:
PCWTJ87OXNnGhwzvzqvbhepi2qQM6PhMdNHn7V9UuVw|
But I am currently getting the related:
Found attribute: expiry with value: 2014-10-29T22:20:00Z
xml file:
<?xml version="1.0"?>
<Inrix responseId="63448807-78d3-4ee8-90d6-a8b64abff8fc" statusText="" statusId="0" createdDate="2014-10-29T21:21:55Z" versionNumber="5.4" copyright="Copyright INRIX Inc." docType="GetSecurityToken">
<AuthResponse>
<AuthToken expiry="2014-10-29T22:20:00Z">PCWTJ87OXNnGhwzvzqvbhepi2qQM6PhMdNHn7V9UuVw|</AuthToken>
<ServerPath>devzone.inrix.com/traffic/inrix.ashx</ServerPath>
<ServerPaths>
<ServerPath region="NA" type="API">http://na.api.inrix.com/Traffic/Inrix.ashx</ServerPath>
<ServerPath region="NA" type="TTS">http://na-rseg-tts.inrix.com/RsegTiles/tile.ashx</ServerPath>
</ServerPaths>
</AuthResponse>
</Inrix>
This is the code I wrote to parse the xml file above:
DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
DocumentBuilder builder =factory.newDocumentBuilder();
Document document = builder.parse(new File(inputfile));
document.getDocumentElement().normalize();
NodeList AuthTokens = document.getElementsByTagName("AuthToken");
//NodeList AuthTokens = document.getElementsByTagName("ServerPath");
int num = AuthTokens.getLength();
for (int i=0; i<num;i++){
Element node = (Element) AuthTokens.item(i);
NamedNodeMap attributes = node.getAttributes();
int numAttrs = attributes.getLength();
for (int j=0; j<numAttrs;j++){
Attr attr = (Attr) attributes.item(j);
String attrName = attr.getNodeName();
String attrValue = attr.getNodeValue();
System.out.println(attr.getParentNode());
System.out.println("Found attribute: " + attrName + " with value: " + attrValue);
}
}
How do I get the correct value?

I believe you want the contents of the node, not its' attributes. Change your Element to Node and then you can call Node.getTextContent()
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File(inputfile));
document.getDocumentElement().normalize();
NodeList AuthTokens = document.getElementsByTagName("AuthToken");
// NodeList AuthTokens = document.getElementsByTagName("ServerPath");
int num = AuthTokens.getLength();
for (int i = 0; i < num; i++) {
Node node = AuthTokens.item(i);
String token = node.getTextContent();
System.out.println(token);
}
Output is (as requested)
PCWTJ87OXNnGhwzvzqvbhepi2qQM6PhMdNHn7V9UuVw|

Related

Return values from xml, xml Iteration

I have an xml file as such
<?xml version="1.0" encoding="UTF-8"?>
<folder name="c">
<folder name="program files">
<folder name="uninstall information" />
</folder>
<folder name="users"/>
</folder>
I want to print out "c", "program files", "uninstall information" and "users" what i finally want to do is to print out only values of the name attribute with string starting from u , therefore users and uninsall information.
But i have not been able to print all the values out,
Below is my code where you can see i have tried to ways but no success so far.
public static Collection<String> folderNames(String xml, char startingLetter) throws Exception {
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
FileInputStream fis = new FileInputStream("src/main/resources/test.xml");
org.xml.sax.InputSource is = new InputSource(fis);
Document doc = documentBuilder.parse(is);
NodeList nodeList = doc.getElementsByTagName("*");
for(int i =0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
/// Tried this
if(node.getNodeType() == Node.ELEMENT_NODE) {
String value = node.getTextContent();
System.out.println("value:::" +value);
}
/// tried this
// Element element = (Element)nodeList.item(i);
// NamedNodeMap attributes = element.getAttributes();
// Node nodeValue1 = nodeList.item(i);
// System.out.println(nodeValue1.getAttributes().item(i));
}
} catch (Exception e) {
e.getMessage();
}
return Collections.EMPTY_LIST;
}
for speedy test my imported classes looks like test
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
My approach without using getElementByTagsName
Document doc = documentBuilder.parse(is);
NodeList nodeList = doc.getElementsByTagName("folder");
for(int i =0; i < nodeList.getLength(); i++) {
if (nodeList.item(i).hasChildNodes()) {
for(int i1 = 0; i1 < nodeList.item(i).getChildNodes().getLength(); i1++) {
Node node = nodeList.item(i).getChildNodes().item(i);
System.out.println(node.getAttributes().item(i));
}
}
Node nodeValue1 = nodeList.item(i);
System.out.println(nodeValue1.getAttributes().item(i));
This isnt complete but it will require a recursive call, due to hierarchy in the xml
Example of printing all folder names starting with u:
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<folder name=\"c\">\n" +
" <folder name=\"program files\">\n" +
" <folder name=\"uninstall information\" />\n" +
" </folder>\n" +
" <folder name=\"users\"/>\n" +
"</folder>";
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc = documentBuilder.parse(new InputSource(new StringReader(xml)));
NodeList nodeList = doc.getElementsByTagName("folder");
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
String name = element.getAttribute("name");
if (name.startsWith("u"))
System.out.println(name);
}
Output
uninstall information
users
You almost had it. First you have to identify the XML element, which you did.
if(node.getNodeType() == Node.ELEMENT_NODE) {
String value = node.getTextContent();
System.out.println("value:::" +value);
}
but instead of getting invoking getTextContent(), you need to find the attribute in that element. Some variation of the below. Of course, if there is more than one attribute you will need to accomodate looking at them all (using node.getAttributes().getLength()):
if(node.getNodeType() == Node.ELEMENT_NODE) {
if (node.getAttributes() != null) {
String name = node.getAttributes().item(0).getNodeName();
String value = node.getAttributes().item(0).getNodeValue();
System.out.println("attribute name:::" +name + " value:::" +value);
}
}

XML parsing to Java - getting root attribute value

I'm having a slight problem with XML parsing.
I'm creating a function where the parameter is a certain "element" from the XML file.
When found, I want to return the value of the root attribute.
Here's my code:
FileInputStream file = new FileInputStream(new File("C:\\Users\\Grizzly\\Java\\Projet_16_17-20161214\\bdd.xml"));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("type");
for (int temp = 0; temp < nList.getLength(); temp++)
{
Node nNode = nList.item(temp);
if(nNode.toString().equalsIgnoreCase(element))
{
Element eElement = (Element) nNode;
System.out.println("Taxe= "+ eElement.getAttribute("taxe"));
}
}
}
Any idea on how to do this?
Here's my XML file:
<?xml version="1.0"?>
-<types>
-<type id="Nourriture" taxe="0.1">
<element>pomme</element>
<element>fraise</element>
<element>fromage</element>
<element>viande rouge </element>
</type>
-<type id="Matiere Premiere" taxe="0.2">
<element>fer</element>
<element>polypropylene</element>
</type>
-<type id="Element Solide" taxe="0.3">
<element>voiture</element>
<element>planche surf</element>
<element>pistolet</element>
</type>
</types>
In my code, I tried to get the elements of a certain node from the nodelist and then compare it to the the string "element" which is the input of the user, and if they match it will check the attribute value of taxe linked to it.
Thanks in advance.
EDIT: I'm getting closer to what I need:
NodeList nList = doc.getElementsByTagName("type");
for (int temp = 0; temp < nList.getLength(); temp++)
{
Node nNode = nList.item(temp);
NodeList nChildren = nNode.getChildNodes();
Element eElement = (Element) nNode;
for(int i = 0; i < nChildren.getLength(); i++)
{
String onElement = eElement.getElementsByTagName("element").item(i).getTextContent();
if(onElement.equalsIgnoreCase(element))
{
System.out.println("id : " + eElement.getAttribute("id"));
System.out.println("taxe : " + eElement.getAttribute("taxe"));
break;
}
}
}
But it's only reading the first element... and item(i) isn't working.
Any idea?
If I understand you correctly, you are trying to fetch specific attributes (id and taxe) of all the document nodes having at least one child element with specific name (element).
Although the problem can be solved by iterating the DOM and keeping the states, I would rather delegate this task to XPath. A code with XPath will look cleaner and be more maintainable. For example, in order to fetch all elements having attributes id and taxe and a child element element you can use an XPath expression like //*[#id and #taxe element]. The matching nodes are fetched in a single line. You can simply iterate the nodes and collect the attributes as shown in the following example.
Example
public static void main(String args[]) {
String element = args.length > 0 ? args[0] : "element";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
FileInputStream file = new FileInputStream(new File("/some/file.xml"));
Document doc = builder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "//*[#id and #taxe and " + element + "]";
NodeList nodeList = (NodeList) xPath.compile(expression)
.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
NamedNodeMap attributes = node.getAttributes();
for (int j = 0; j < attributes.getLength(); j++) {
Node aNode = attributes.item(j);
System.out.printf(
"%s: %s\n",
aNode.getNodeName(),
aNode.getNodeValue()
);
}
}
} catch (Exception e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
Sample Output
id: Nourriture
taxe: 0.1
id: Matiere Premiere
taxe: 0.2
id: Element Solide
taxe: 0.3
Note, the sample above prints all attributes of the parent element. If you want to print only specific ones, you can, obviously, add a trivial check like this:
String aName = aNode.getNodeName();
if (aName.equals("taxe")) { // ...
But you can actually filter out the attributes with XPath:
String expression = "//*[ " + element + "]/#*[name() = 'id' or name() = 'taxe']";
NodeList nodeList = (NodeList) xPath.compile(expression)
.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
System.out.printf("%s: %s\n", node.getNodeName(), node.getNodeValue());
}
The XPath expression above fetches all attribute nodes having names equal to whether id, or taxe. If you want all attributes, simply remove the last condition:
String expression = "//*[ " + element + "]/#*";

how to parse xml in java using Google Geocode

The code
try{
URL url = new URL("http://maps.googleapis.com/maps/api/geocode/xml?address=Riyadh&sensor=false");
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String line;
while(null != (line = reader.readLine())){
System.out.println(line);
}
}catch(Exception e){
e.printStackTrace();
}
The output:
Server is Ready....
<?xml version="1.0" encoding="UTF-8"?>
<GeocodeResponse>
<status>OK</status>
<result>
<type>locality</type>
<type>political</type>
<formatted_address>Riyadh Saudi Arabia</formatted_address>
<address_component>
<long_name>Riyadh</long_name>
<short_name>Riyadh</short_name>
<type>locality</type>
<type>political</type>
</address_component>
<address_component>
<long_name>Riyadh Province</long_name>
<short_name>Riyadh Province</short_name>
<type>administrative_area_level_1</type>
<type>political</type>
</address_component>
<address_component>
<long_name>Saudi Arabia</long_name>
<short_name>SA</short_name>
<type>country</type>
<type>political</type>
</address_component>
<geometry>
<location>
<lat>24.7135517</lat>
<lng>46.6752957</lng>
</location>
<location_type>APPROXIMATE</location_type>
<viewport>
<southwest>
<lat>24.2939113</lat>
<lng>46.2981033</lng>
</southwest>
<northeast>
<lat>25.1564724</lat>
<lng>47.3469543</lng>
</northeast>
</viewport>
<bounds>
<southwest>
<lat>24.2939113</lat>
<lng>46.2981033</lng>
</southwest>
<northeast>
<lat>25.1564724</lat>
<lng>47.3469543</lng>
</northeast>
</bounds>
</geometry>
<place_id>ChIJmZNIDYkDLz4R1Z_nmBxNl7o</place_id>
</result>
</GeocodeResponse>
I'm trying to use Google geocode API to get the coordinates of a city, but I'm facing problem that how can i parse the XML response to retrieve the longitude and the latitude of the city enclosed within the (<location></location>) section.
Check the org.w3c.dom.* java library for xml parsing, or JDOM... if you want to access something in a hierarchical way.
Please check XML Parsers in JAVA for more alternatives.
After implementing the code, you just kinda call for the element "location", and iterate through its children and retrieve the values you want.
here's an example:
String xmlRecords = "<data><employee><name>A</name>"
+ "<title>Manager</title></employee></data>";
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlRecords));
Document doc = db.parse(is);
NodeList nodes = doc.getElementsByTagName("employee");
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList name = element.getElementsByTagName("name");
Element line = (Element) name.item(0);
System.out.println("Name: " + getCharacterDataFromElement(line));
NodeList title = element.getElementsByTagName("title");
line = (Element) title.item(0);
System.out.println("Title: " + getCharacterDataFromElement(line));
}
}
String xmlRecords = "<data><employee><name>A</name>"
+ "<title>Manager</title></employee></data>";
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlRecords));
Document doc = db.parse(is);
NodeList nodes = doc.getElementsByTagName("employee");
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList name = element.getElementsByTagName("name");
Element line = (Element) name.item(0);
System.out.println("Name: " + getCharacterDataFromElement(line));
NodeList title = element.getElementsByTagName("title");
line = (Element) title.item(0);
System.out.println("Title: " + getCharacterDataFromElement(line));
}
}
public static String getCharacterDataFromElement(Element e) {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;
return cd.getData();
}
return "";
}
}

getNodeValue returnining null?

Hi I am trying to parse and XML file from an url, my NodeList contains values but getNodeValue for each node returns null. Can anybody help me?
This is my method where I parse the xml.
public ArrayList xmloku(String url) {
ArrayList xmllistesi = new ArrayList();
try {
URL xmlyolu = new URL(url);
DocumentBuilderFactory dFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder dBuilder = dFactory.newDocumentBuilder();
Document document = dBuilder.parse(new InputSource(xmlyolu
.openStream()));
document.getDocumentElement().normalize();
NodeList nodeListCountry = document
.getElementsByTagName("karikatur");
for (int i = konum; i < nodeListCountry.getLength(); i++) {
Node node = nodeListCountry.item(i);
Element elementMain = (Element) node;
xmllistesi.add(elementMain.getNodeValue());
}
Instead of getNodeValue() try using getTextContent()
for (int i = konum; i < nodeListCountry.getLength(); i++) {
Node node = nodeListCountry.item(i);
Element elementMain = (Element) node;
xmllistesi.add(elementMain.getTextContent());
}

Java XML Reading

I've been wondering how to read XML files, but before you answer, read the whole post.
For example I have:
<?xml version="1.0" encoding="UTF-8"?>
<messages>
<incoming id="0" class="HelloIlikeyou" />
</messages>
What I want, is get all values from the tag . I want to place it in a dictionary, which key is incoming/outgoing, and then it will contain a list of Pair as value, with as key the id value and as value the class value.
So I got this:
HashMap<String, List<Pair<Integer, String>>> headers = new HashMap<>();
Then it will store this:
HashMap.get("incoming").add(new Pair<>("0", "HelloIlikeyou"));
But I don't know how to do it, I already got a part but it aint working:
File xml = new File(file);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xml);
doc.getDocumentElement().normalize();
NodeList nodes = doc.getElementsByTagName("messages");
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
System.out.println("Type: " + node.getNodeValue() + " packet ID " + node.getUserData("id"));
}
You can use JAXB, i think that is the best way. take a look of this:
Jaxb tutorial
This is what you want:
public static void main(final String[] args)
throws ParserConfigurationException, SAXException, IOException {
File xml = new File(file);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xml);
doc.getDocumentElement().normalize();
NodeList nodes = doc.getElementsByTagName("messages");
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
for (int j = 0; j < node.getChildNodes().getLength(); j++) {
Node child = node.getChildNodes().item(j);
if (!child.getNodeName().equals("#text")) {
NamedNodeMap attributes = child.getAttributes();
System.out.println("Type: " + child.getNodeName()
+ " packet ID " + attributes.getNamedItem("id")
+ " - class: " + attributes.getNamedItem("class"));
}
}
}
}
This gives me the following output:
Type: incoming packet ID id="0" - class: class="HelloIlikeyou"
Node node = nodes.item(i);
if (node instanceOf Element) {
Element elem = (Element)node;
String id = elem.getAttribute("id");
...
So you were almost there. The W3C classes are a bit old-stylish.
Use one of the many available libraries that will do that for you, for example XStream:
http://x-stream.github.io/

Categories