Im trying to get the number of child elements of a parent element from a XML file using JAVA. Here is the code I'm working with:
File fXmlFile = new File("SearchPromotions.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
NodeList l = doc.getElementsByTagName("TestCase");
Node parentNode = l.item(0);
int count = parentNode.getChildNodes().getLength();
System.out.println(count);
And here is the XML file:
<TestCase>
<SelectedDataTableNames name="SearchData"> </SelectedDataTableNames>
<Open page="hsbc" ms="5000" />
<Click object="hsbc.Personal_Link" />
<Click object="hsbc.CreditCard_tab" />
<Call businessComponent="Global.Verify_Search">
<Param name="HotelName_Param" value="#SearchData_link" />
</Call>
<CheckElementPresent object="hsbc.Img_Hotel_logo" Identifire="Hotel_Name_PARAM:#SearchData_ResultHotelName" fail="true" customErrorMessage="Searched hotel name is not present in the page." />
</TestCase>
The problem im facing is that it is printing a wrong value. The value printed is 13. But as you can see there are only 6 child elements for the parent element "TestCase". Where did i go wrong. Please help
public static void main(String[] args) throws Exception {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
String fileContent = readFile("SearchPromotions.xml");// Read trimmed file
InputStream in = new ByteArrayInputStream(fileContent.getBytes("UTF-8"));// Create stream to pass it to parser()
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(in);
NodeList l = doc.getElementsByTagName("TestCase");
Node parentNode = l.item(0);
int count = parentNode.getChildNodes().getLength();
System.out.println(count);
}
private static String readFile(String pathname) throws IOException {
File file = new File(pathname);
StringBuilder fileContents = new StringBuilder((int) file.length());
Scanner scanner = new Scanner(file);
try {
while (scanner.hasNextLine()) {
fileContents.append(scanner.nextLine().trim()); // Trim the whitespace. This resuls in TEXT_NODE.
}
return fileContents.toString();
} finally {
scanner.close();
}
}
There are some white space charcters in your XML which will result in extra nodes. Try the above solution hope it helps.
The children of a node include whitespace text nodes as well as child element nodes.
Why not just do this with XPath - it's so much less hassle!
With Saxon and XPath 2.0 it would be
Processor p = new Processor(false);
XdmNode doc = p.newDocumentBuilder().build(
new StreamSource(new File("searchPromotions.xml")));
XdmItem result = p.newXPathCompiler().evaluateSingle("/TestCase/count(*)", doc);
System.out.println(result.getStringValue());
Found the answer for the question. It works. The problem i had was ELEMENT_NODE. We have to filter ELEMENT_NODE. Here is the working code. Thanks for all those who helped be over there.
File fXmlFile = new File("SearchPromotions.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
Element docEle = doc.getDocumentElement();
NodeList nl = docEle.getChildNodes();
if (nl != null && nl.getLength() > 0) {
for (int i = 0; i < nl.getLength(); i++) {
if (nl.item(i).getNodeType() == Node.ELEMENT_NODE) {
Element el = (Element) nl.item(i);
System.out.println(el);
}
}
}
Related
I have to get Key and values from XMl File, I am getting Key but not value
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("laptops.xml"));
document.getDocumentElement().normalize();
NodeList laptopList = document.getElementsByTagName("string");
for(int i = 0; i <laptopList.getLength(); i++) {
Node laptop = laptopList.item(i);
if(laptop.getNodeType() == Node.ELEMENT_NODE) {
Element laptopElement = (Element) laptop;
System.out.println(laptopElement.getAttribute("name"));
}
}
XML File:
<laptops>
<string name="usb">100</string>
<string name="charger">200</string>
</laptops
Result Should be Like this :
usb: 100,
charger: 200
The values 100 and 200 are in Textnodes. You can get the content with:
laptopElement.getTextContent()
Good Day,
Is it possible to parse XML content by not using its absolute path?
So it goes like this I have two variables:
replyInXml = "<company><staff id="1001"><firstname>yong</firstname><lastname>mook kim</lastname><nickname>mkyong</nickname><salary>100000</salary></staff></company>"
xmlFilePath = "c:\folder\file.xml"
In my Java code, I use the absolute path and I got the xml result I wanted. My question is, is it possible to parse it using the converted xml string (replyInXml) variable above.
File fXmlFile = new File(xmlFilePath);
Full Code:
public class XmlReader {
public String showProcessFlowID(String replyInXML) {
String processFlowResult = "";
try {
File fXmlFile = new File(replyInXML);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("SUIFT:TEST_ATTR_LIST");
// System.out.println("----------------------------");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
String processStep = "PROCESS STEP=" + eElement.getElementsByTagName("SUIFT:TEST_STAGE").item(0).getTextContent();
String flowID = "FLOW ID=" + eElement.getElementsByTagName("SUIFT:FLOW_ID").item(0).getTextContent();
processFlowResult = processStep + "\n" + flowID;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return processFlowResult;
}
public static void main(String args[]) {
//I want to use this but negative result since the File() parameter need xml file
String xmlContent = "<company><staff><firstname>yong</firstname><lastname>mook kim</lastname><nickname>mkyong</nickname><salary>100000</salary></staff></company>";
//This is working
String xmlPath = "C:\\folder1\\sampleReply.xml";
XmlReader processFlow = new XmlReader();
String reply = processFlow.showProcessFlowID(xmlPath);
System.out.println(reply);
}
}
Please advise.
TIA
Yes.You can user xml string to parse.
String xmlStr="";
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new ByteArrayInputStream(xmlStr.getBytes("UTF-8")));
I am trying to extract the xml values in java
Below is the xml and I want to extract userUuid from the xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ResponseSet vers="1.0" svcid="session" reqid="3">
<Response><![CDATA[
<SessionResponse vers="1.0" reqid="0">
<GetSession>
<Session sid="******" stype="user" cid="uid=****" cdomain="o=nhs" maxtime="0" maxidle="0" maxcaching="0" timeidle="0" timeleft="****" state="valid">
<Property name="userUuid" value="555524799109"></Property>
</Session>
</GetSession>
</SessionResponse>]]>
</Response>
</ResponseSet>
I referred this links none of them worked from me
Read XML in Java with XML attributes
How can I read Xml attributes using Java?
Also I tried
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
dbFactory.setValidating(false);
DocumentBuilder docBuilder = dbFactory.newDocumentBuilder();
ByteArrayInputStream inputStream = new ByteArrayInputStream(sXMLData.getBytes("UTF-8"));
Document document = docBuilder.parse(inputStream);
NodeList nodeList = document.getElementsByTagName("Property");
System.out.println(nodeList.getLength());
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
String el = element.getAttribute("name");
System.out.println(el);
}
Just posting an answer if someone faces same issue
public String parseXMLResponse(String sXMLData) throws IOException, SAXException, ParserConfigurationException {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
dbFactory.setValidating(false);
DocumentBuilder docBuilder = dbFactory.newDocumentBuilder();
ByteArrayInputStream inputStream = new ByteArrayInputStream(sXMLData.getBytes("UTF-8"));
Document document = docBuilder.parse(inputStream);
NodeList nodeList = document.getElementsByTagName("Property");
String userUuId = null;
for (int i = 0; i < nodeList.getLength(); i++) {
Element element = (Element) nodeList.item(i);
String el = element.getAttribute("name");
if(el.equalsIgnoreCase("UserId"))
{
userUuId = element.getAttribute("value");
break;
}
}
return userUuId;
}
I've got XPath of XML with it's structure like
<Statement xsi:type="conditionStatement">
<Id>CONDITION_0001</Id>
<Bounds>
<xValue>13</xValue>
<yValue>145</yValue>
<Height>402</Height>
<Width>513</Width>
</Bounds>
.........
.........
</statement>
Xpath takes me to xsi:type. But when I'm trying to get the name of node which is "statement" as expected, it's getting null.
My code for this is:-
nodeList = (NodeList) xPath.compile(xPathSrcFile).evaluate(xmlDocument, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
nodeList.item(i).getParentNode();
}
For rest of the cases, code is working perfectly fine but when it gets to "xsi", code is throwing nullpointer exception.
Need some help to get node name from this.
try this
NodeList nodeList = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputStream inputStream= new FileInputStream(file);//xmlDocument as file
Reader reader = new InputStreamReader(inputStream,"ISO-8859-1");
InputSource is = new InputSource(reader);
is.setEncoding("ISO-8859-1");
Document doc = db.parse(is);
Element docEle = doc.getDocumentElement();
nodeList = docEle.getElementsByTagName("Statement");
1 Your XML file is incorrect:
it begins with Statement
and ends with /statement
2 you need this at root tag:
< root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
3 to get the name of you tag, use:
nodeList.item(i).getTagName();
4 what is your Xpath ?
I have a set of XML string outputs from a natural language tool and need to retrieve values out of them, also provide null value to those tags that are not presented in the output string. Tried to use the Java codes provided in Extracting data from XML using Java but it doesn't seem to work.
Current sample tag inventory is listed below:
<TimeStamp>, <Role>, <SpeakerId>, <Person>, <Location>, <Organization>
Sample XML output string:
<TimeStamp>00.00.00</TimeStamp> <Role>Speaker1</Role><SpeakerId>1234</SpeakerId>Blah, blah, blah.
Desire outputs:
TimeStamp: 00.00.00
Role: Speaker1
SpeakerId: 1234
Person: null
Place: null
Organization: null
In order to use the Java codes provided in above link (in updated code), I inserted <Dummy> and </Dummy> as follows:
<Dummy><TimeStamp>00.00.00</TimeStamp><Role>Speaker1</Role><SpeakerId>1234</SpeakerId>Blah, blah, blah.</Dummy>
However, it returns dummy and null only. Since I'm still a newbie to Java, detailed explanations will be much appreciated.
Try this way :D hope can help you
File fXmlFile = new File("yourfile.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
You can get child node list like this:
NodeList nList = doc.getElementsByTagName("staff");
Get the item like this:
Node nNode = nList.item(temp);
Example Site
This is what I ended up doing for my Java wrapper (Show TimeStamp only)
public class NERPost {
public String convertXML (String input) {
String nerOutput = input;
try {
DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(nerOutput));
Document doc = docBuilder.parse(is);
// normalize text representation
doc.getDocumentElement ().normalize ();
NodeList listOfDummies = doc.getElementsByTagName("dummy");
for(int s=0; s<listOfDummies.getLength() ; s++){
Node firstDummyNode = listOfDummies.item(s);
if(firstDummyNode.getNodeType() == Node.ELEMENT_NODE){
Element firstDummyElement = (Element)firstDummyNode;
//Convert each entity label --------------------------------
//TimeStamp
String ts = "<TimeStamp>";
Boolean foundTs;
if (foundTs = nerOutput.contains(ts)) {
NodeList timeStampList = firstDummyElement.getElementsByTagName("TimeStamp");
//do it recursively
for (int i=0; i<timeStampList.getLength(); i++) {
Node firstTimeStampNode = timeStampList.item(i);
Element timeStampElement = (Element)firstTimeStampNode;
NodeList textTSList = timeStampElement.getChildNodes();
String timeStampOutput = ((Node)textTSList.item(0)).getNodeValue().trim();
System.out.println ("<TimeStamp>" + timeStampOutput + "</TimeStamp>\n")
} //end for
}//end if
//other XML tags
//.....
}//end if
}//end for
}
catch...
}//end try
}}