I need to loop through all chilnodes in the parent node (callEvents) and save each time the position of the child node.(First call event, second call event...). I'm stack in how to get the position of each child node in the parent node java/xpath?
say I have the following xml:
<callEvents>
<gprsCall>...</gprsCall>
<gprsCall>...</gprsCall>
<mobileOrigintaedCall>...</mobileOrigintaedCall>
<gprsCall>...</gprsCall>
<gprsCall>...</gprsCall>
</callEvents>
So the code should return:
My first gprsCall position = 1
My second gprsCall position = 2
My first mobileOriginatedCall position = 3
My third gprsCall position = 4
My fourth gprsCall position = 5
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.xpath.XPathFactory;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathConstants;
import java.io.StringReader;
import org.xml.sax.InputSource;
class myxml {
static final String xml = "<callEvents>\n"
+ "<gprsCall>...</gprsCall>\n"
+ "<gprsCall>...</gprsCall>\n"
+ "<mobileOrigintaedCall>...</mobileOrigintaedCall>\n"
+ "<gprsCall>...</gprsCall>\n"
+ "<gprsCall>...</gprsCall>\n"
+ "</callEvents>";
public static void main (String... args) throws Throwable {
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xml)));
XPathExpression xpath = XPathFactory.newInstance().newXPath().compile("/callEvents/*");
NodeList nodelist = (NodeList) xpath.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodelist.getLength(); i++) {
System.out.println("Position: " + (i + 1)
+ ", name: " + nodelist.item(i).getNodeName());
}
} catch (Throwable e) {
throw e;
}
}
}
Iterate over the XPath callEvents/* and use the position() function to get the position.
This is an XSLT example:
<xsl:template match="/callEvents/*">
<xsl:value-of select="concat(local-name(),' - ',position() div 2)" />
</xsl:template>
Related
I am trying to parse this xml file but I'm only getting the root elements and not it's child nodes.
I need information of some specific values from the nodes like using .item() method. Since, I'm not entering it's child nodes so it didn't give me the specified values. Please help me solving this...
XML file
<Ws>
<Id V='862631039910699'>
<Dt V='08/07/22;11/25'>
<T V='24.3;24.3;24.3'/>
<H V='98.0;98.0;98.0'/>
<W V='1.3;272'/>
<G V='25;2.4'/>
<A V='0.00;468;472;471'/>
<D V='0.00;8.9;8.065;0.0000;0.0000'/>
</Dt>
</Id>
</Ws>
package api;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;
public class Web{
public static void main(String argv[])
{
try {
File file = new File("C:\\Users\\Prakhar\\OneDrive\\Desktop\\WBE2.xml.txt");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();
System.out.println("Root element: " + doc.getDocumentElement().getNodeName());
NodeList nodeList = doc.getElementsByTagName("Ws");
for (int i = 0; i < nodeList.getLength(); ++i) {
Node node = nodeList.item(i);
System.out.println("\nNode Name :" + node.getNodeName());
if (node.getNodeType()== Node.ELEMENT_NODE) {
Element tElement = (Element)node;
System.out.println("IMEI: " +
doc.getDocumentElement().getChildNodes().item(0).getFirstChild().getChildNodes().item(0).getAttributes().getNamedItem("V").getNodeValue());
System.out.println("Date/Time: " +
doc.getDocumentElement().getChildNodes().item(0).getFirstChild().getChildNodes().item(1).getAttributes().getNamedItem("V").getNodeValue());
System.out.println("Temperature: " +
doc.getDocumentElement().getChildNodes().item(0).getFirstChild().getChildNodes().item(2).getAttributes().getNamedItem("V").getNodeValue());
System.out.println("Humidity: " +
doc.getDocumentElement().getChildNodes().item(0).getFirstChild().getChildNodes().item(1).getAttributes().getNamedItem("V").getNodeValue());
System.out.println("Wind Speed: " +
doc.getDocumentElement().getChildNodes().item(0).getFirstChild().getChildNodes().item(2).getAttributes().getNamedItem("V").getNodeValue());
}
}
}
catch (Exception e) {
System.out.println(e);
}
}
}
I wouldlike to search in my xml file all attribut (name) without use element tag node :
xml :
<test 1><test1/>
<test2> <test2/>
<test 3 id="aaa"> </test3>
<test 5> </test5>
<test 6 id="bbb" name="ijof"> </test6>
JAVA :
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File(path));
root = document.getDocumentElement();
String attribut = root.getAttribute("name");
System.out.println(attribut); // Expected ijof
Did you execute your code at least once? I dont't think so. Otherwise you would have surely noticed that your XML cannot be parsed.
There are several flaws in your example XML:
No root element.
Wrong end tags: It should be <test1></test1> and not <test1><test1/>.
Element names must not contain whitespace and start and end tag must match. It should be <test5> </test5> and not <test 5> </test5>
Apart of that you can use XPATH to get all elements with a name attribute.
Here is a complete example with the XML as a string but this should be irrelevant:
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.IOException;
import java.io.StringReader;
public class FindNameAttribute {
private static final String XML =
"<root>\n" +
" <test1></test1>\n" +
" <test2> </test2>\n" +
" <test3 id=\"aaa\"> </test3>\n" +
" <test4 name=\"4\"/>\n" +
" <test5> </test5>\n" +
" <test6 id=\"bbb\" name=\"ijof\"> </test6>\n" +
" <test7 id=\"bbb\"><child name=\"childname\"/> </test7>\n" +
"</root>\n";
public static void main(String[] args) {
System.out.println(XML);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
StringReader reader = new StringReader(XML);
InputSource source = new InputSource(reader);
Document document = builder.parse(source);
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = (NodeList) xpath.evaluate("//*[#name]", document, XPathConstants.NODESET);
for(int i = 0; i < nodes.getLength(); i++) {
Element el = (Element) nodes.item(i);
String elementName = el.getTagName();
String nameAttribute = el.getAttribute("name");
System.out.println(String.format("Element name: %s, name attribute: %s", elementName, nameAttribute));
}
} catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException e) {
e.printStackTrace();
}
}
}
This is the output:
<root>
<test1></test1>
<test2> </test2>
<test3 id="aaa"> </test3>
<test4 name="4"/>
<test5> </test5>
<test6 id="bbb" name="ijof"> </test6>
<test7 id="bbb"><child name="childname"/> </test7>
</root>
Element name: test4, name attribute: 4
Element name: test6, name attribute: ijof
Element name: child, name attribute: childname
The relevant XPATH expression is: //*[#name]
//: Looks for every element in the document
*: Placeholder for element name. Each name matches.
*[#name]: The [] denotes the predicate. We only want elements with a name attribute.
#: Means the following name is the name of an attribute. Whithout it would be interpreted as an element name
I have a XML format stored in a String variable. It's like this,
String xml = "myXML";
<?xml version="1.0" encoding="UTF-8"?>
<shiporder orderid="889923"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="shiporder.xsd">
<orderperson>John Smith</orderperson>
<shipto>
<name>Ola Nordmann</name>
<address>Langgt 23</address>
<city>4000 Stavanger</city>
<country>Norway</country>
</shipto>
<item>
<title>Empire Burlesque</title>
<note>Special Edition</note>
<quantity>1</quantity>
<price>10.90</price>
</item>
<item>
<title>Hide your heart</title>
<quantity>1</quantity>
<price>9.90</price>
</item>
</shiporder>
In above XML you can see there are multiple ITEMS. Can somebody tell using a loop or something,How can i store each Item in a arrayList or something? I would love if i can give it a try, But unfortunately i don't have an idea how to do it.
Appreciate if someone could help?
Please note that the XML is stored in the string variable as a String.
You can parse XML pretty easily in Java.
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import java.io.StringReader;
//...
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(YOUR_XML_STRING));
Document xml = builder.parse(is);
Element root = xml.getDocumentElement();
Node node = root.getFirstChild();
while(node != null) {
//Browse nodes
node = node.getNextSibling();
}
} catch (ParserConfigurationException | SAXException | IOException e) {
Logger.getGlobal().log(Level.SEVERE, "Couldn't load config", e);
}
Note that you can also search by id or tag name for example :
xml.getElementsByTagName("item"); //Returns a NodeList
Read the doc for more information.
You can create an ArrayList of items like below code :
import java.io.StringReader;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
public class Lab {
public static Map<String,List<String>> hMap = new LinkedHashMap<>();
public static void main(String r[]) {
// your xml string
String s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
"\r\n" +
"<shiporder orderid=\"889923\"\r\n" +
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\r\n" +
"xsi:noNamespaceSchemaLocation=\"shiporder.xsd\">\r\n" +
" <orderperson>John Smith</orderperson>\r\n" +
" <shipto>\r\n" +
" <name>Ola Nordmann</name>\r\n" +
" <address>Langgt 23</address>\r\n" +
" <city>4000 Stavanger</city>\r\n" +
" <country>Norway</country>\r\n" +
" </shipto>\r\n" +
" <item>\r\n" +
" <title>Empire Burlesque</title>\r\n" +
" <note>Special Edition</note>\r\n" +
" <quantity>1</quantity>\r\n" +
" <price>10.90</price>\r\n" +
" </item>\r\n" +
" <item>\r\n" +
" <title>Hide your heart</title>\r\n" +
" <quantity>1</quantity>\r\n" +
" <price>9.90</price>\r\n" +
" </item>\r\n" +
"</shiporder>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(s));
Document doc = builder.parse(is);
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("item");
for (int parameter = 0; parameter < nodeList.getLength(); parameter++) {
List<String> items = new ArrayList<>();
Node node = nodeList.item(parameter);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) node;
String title = eElement.getElementsByTagName("title").item(0).getTextContent();
String quantity = eElement.getElementsByTagName("quantity").item(0).getTextContent();
String price = eElement.getElementsByTagName("price").item(0).getTextContent();
items.add(title);
items.add(quantity);
items.add(price);
hMap.put("item" + parameter, items);
}
}
} catch (Exception e) {
e.printStackTrace();
}
hMap.forEach((h,k) -> {
System.out.println(h + ":" + k); // you can get values like hMap.get("item0") and next hMap.get("item1") etc.
});
}
}
Hope that helps you.
I have only collected common elements of item.
Hope that helps you:)
I don't know how to explain my situation, I can provide example below.
I have an XML file to be read in Java, something like this:
<Author AffiliationIDS="Aff1">
<AuthorName DisplayOrder="Western">
<GivenName>Wei</GivenName>
<GivenName>Long</GivenName>
<FamilyName>
<Value>Tan</Value>
</FamilyName>
</AuthorName>
</Author>
As you can see the <FamilyName> tag, inside the <FamilyName> tag is surrounded by a Value tag. This is because in the xsd it stated the element as maxOccurs="unbounded" which mean more than one value can be in that element tag. How should I modify the code so that it can read in the <FamilyName> tag and get Value tag element no matter how many occurrence of the Value exist?
Example:
<FamilyName>
<Value>Sarah</Value>
<Value>Johnson</Value>
</FamilyName>
The code look like this.
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;
public class ReadXMLFile {
public static void main(String argv[]) {
try {
File fXmlFile = new File("/fileaddress/test-1.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("AuthorName");
System.out.println("----------------------------");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
System.out.println("\nCurrent Element :" + nNode.getNodeName());
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
System.out.println("Given Name : " + eElement.getElementsByTagName("GivenName").item(0).getTextContent());
System.out.println("Family Name : " + eElement.getElementsByTagName("FamilyName").item(0).getTextContent());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Get the FamilyName node by getElementsByTagName("FamilyName").item(0) and loop over its child nodes (.getChildNodes()) and get the value of the textNode
Or,
You can even getElementsByTagName("Value") if you are sure that value tag does not occur anywhere else other than inside FamilyName
Here is a code Sample
NodeList children = doc.getElementsByTagName("FamilyName").item(0).getChildNodes();
for(int i=0;i<children.getLength();i++) {
if(children.item(i).getNodeType()== Node.ELEMENT_NODE) {
Element child = (Element)children.item(i);
System.out.println(child.getTextContent());
}
}
I'm just starting out with learning how to process/parse XML data in Java. I'm getting the error, "The method getNodeType() is undefined for the type NodeList" on the line, after my for-loop, that contains:
if (n.getNodeType() == Node.ELEMENT_NODE){
The type of error seems like I forgot to import something, but I believe I got everything. I am using an XML example from microsoft, in the following link:
http://msdn.microsoft.com/en-us/library/ms762271(v=vs.85).aspx
Thanks in advance.
import java.io.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Element;
public class Files {
public static void main (String [] args) throws IOException, ParserConfigurationException{
String address = "/home/leo/workspace/Test/Files/src/file.xml";
File xmlFile = new File(address);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = factory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
doc.getDocumentElement().normalize();
System.out.println(doc.getDocumentElement().getNodeName());
NodeList n = doc.getElementsByTagName("book id");
for (int temp = 0; temp < n.getLength(); temp++){
System.out.println(n.item(temp));
if (n.getNodeType() == Node.ELEMENT_NODE){
Element e = (Element) n;
System.out.println("author : " + e.getAttribute("author"));
System.out.println("title : " + e.getAttribute("title") );
System.out.println("genre : " + e.getAttribute("genre"));
System.out.println("price : " + e.getAttribute("price"));
System.out.println("publish_date : " + e.getAttribute("publish_date"));
System.out.println("description : " + e.getAttribute("description"));
}
}
}
}
You are calling getNodeType() on a NodeList object (n).
You need to call this function on a Node object. Example :
n.item(temp).getNodeType();