In my application, I have an XML file and I want to parse the XML file and extract data from the XML tags. Here is my XML file.
<array>
<recipe>
<name> Crispy Fried Chicken </name>
<description> Deliciously Crispy Fried Chicken</description>
<prepTime>1.5 hours </prepTime>
<instructions>instruction steps</instructions>
<ingredients>
<item>
<itemName>Chicken Parts</itemName>
<itemAmount>2 lbs</itemAmount>
</item>
<item>
<itemName>Salt & Peppers</itemName>
<itemAmount>As teste</itemAmount>
</item>
</ingredients>
</recipe>
<recipe>
<name> Bourben Chicken </name>
<description> A good recipe! A tad on the hot side!</description>
<prepTime>1 hours </prepTime>
<instructions>instruction steps</instructions>
<ingredients>
<item>
<itemName>Boneless Chicken</itemName>
<itemAmount>2.5 lbs</itemAmount>
</item>
<item>
<itemName>Olive Oil</itemName>
<itemAmount>1 -2 tablespoon</itemAmount>
</item>
<item>
<itemName>Olive Oil</itemName>
<itemAmount>1 -2 tablespoon</itemAmount>
</item>
</ingredients>
</recipe>
</array>
I have used DOM parser to parse the above xml file and I have extracted data from <name>, <description>, <prepTime> and <instructions> tags BUT I don't know how to extract data from <ingredients> TAG. You can see my code that I have developed for DOM parser. Here is my DOM parser
public class DOMParser
{
// parse Plist and fill in arraylist
public ArrayList<DataModel> parsePlist(String xml)
{
final ArrayList<DataModel> dataModels = new ArrayList<DataModel>();
//Get the xml string from assets XML file
final Document doc = convertStringIntoXML(xml);
// final NodeList nodes_array = doc.getElementsByTagName("array");
//Iterating through the nodes and extracting the data.
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++)
{
Node node = nodeList.item(i);
if (node instanceof Element)
{
DataModel model = new DataModel();
NodeList childNodes = node.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++)
{
Node cNode = childNodes.item(j);
if (cNode instanceof Element)
{
String content = cNode.getLastChild().getTextContent().trim();
if(cNode.getNodeName().equalsIgnoreCase("name"))
model.setName(content);
else if(cNode.getNodeName().equalsIgnoreCase("description"))
model.setDescription(content);
else if(cNode.getNodeName().equalsIgnoreCase("prepTime"))
model.setPrepTime(content);
else if(cNode.getNodeName().equalsIgnoreCase("instructions"))
model.setInstructions(content);
}
}
dataModels.add(model);
}
}
return dataModels;
}
// Create xml document object from XML String
private Document convertStringIntoXML(String xml)
{
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try
{
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
}
catch (ParserConfigurationException e)
{
System.out.println("XML parse error: " + e.getMessage());
return null;
}
catch (SAXException e)
{
System.out.println("Wrong XML file structure: " + e.getMessage());
return null;
}
catch (IOException e)
{
System.out.println("I/O exeption: " + e.getMessage());
return null;
}
return doc;
}
}
You need to iterate ingredients child nodes like you do it for recipe tag.
But the more easy way is to use XPath.
you can change your code as below.
public ArrayList<DataModel> parsePlist(String xml)
{
final ArrayList<DataModel> dataModels = new ArrayList<DataModel>();
//Get the xml string from assets XML file
final Document doc = convertStringIntoXML(xml);
//final NodeList nodes_array = doc.getElementsByTagName("array");
//Iterating through the nodes and extracting the data.
NodeList nodeList = doc.getDocumentElement().getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++)
{
Node node = nodeList.item(i);
if (node instanceof Element)
{
DataModel model = new DataModel();
NodeList childNodes = node.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++)
{
Node cNode = childNodes.item(j);
if (cNode instanceof Element)
{
String content = cNode.getLastChild().getTextContent().trim();
if(cNode.getNodeName().equalsIgnoreCase("name"))
model.setName(content);
else if(cNode.getNodeName().equalsIgnoreCase("description"))
model.setDescription(content);
else if(cNode.getNodeName().equalsIgnoreCase("prepTime"))
model.setPrepTime(content);
else if(cNode.getNodeName().equalsIgnoreCase("instructions"))
model.setInstructions(content);
else if(cNode.getNodeName().equalsIgnoreCase("ingredients"))
{
Element ingredEle = (Element)cNode;
NodeList ingredList = ingredEle
.getElementsByTagName("ingredients");
for (int i = 0; i < ingredList.getLength(); i++)
{
Element item = (Element)ingredList.item(i);
if(item.hasChildNodes())
{
NodeList itemList = item.getElementsByTagName("item");
for (int j = 0; j < itemList.getLength(); j++)
{
Element itemEle = (Element)itemList.item(j);
if (getNodeValue(itemEle, "itemName") != null)
{
String name = getNodeValue(itemEle, "itemName");
//set name here
}
if (getNodeValue(itemEle, "itemAmount") != null)
{
String amount = getNodeValue(itemEle,"itemAmount");
//set amount here
}
}
}
}
}
}
dataModels.add(model);
}
}
return dataModels;
}
private String getNodeValue(Element element, String elementTemplateLoc) {
NodeList nodes = element.getElementsByTagName(elementTemplateLoc);
return getTextNodeValue(nodes.item(0));
}
Hope this will work for you
Related
Hello so i've looked this question up alot but I couldn't find a solution that worked. I'm basically trying to remove the "job" node as seen declared in line 7 and removed in line 13. There's 0 runtime errors but the node doesn't get removed.
NodeList rootNodes = xml.getElementsByTagName("jobs");
Node rootNode = rootNodes.item(0);
Element rootElement = (Element) rootNode;
NodeList jobsList = rootElement.getElementsByTagName("job");
for (int i = 0; i < jobsList.getLength(); i++) {
Node job = jobsList.item(i);
Element jobElement = (Element) job;
if(jobElement.getAttribute("id").equals(
msgEvent.getMessage().getContentRaw().split(" ")[2]))
{
rootNode.removeChild(job);
msgEvent.getChannel().sendMessage("Removed Job " + jobElement.getAttribute("id") + " (Summary: '" + jobElement.getAttribute("summary") + "')").complete();
}
}
Here's the XML
<?xml version = "1.0"?>
<jobs>
<job payment = "50000" poster="171048434529337344" collect = "asdf" id = "1" summary="asdfd" expires="5/10/18"> </job>
<job payment = "10000" poster="171048434529337344" collect = "asdf" id = "2" summary="asdf" expires="5/10/18"> </job>
</jobs>
since this is too large for comment, Here is my test code and results:
public static void main(String[] args) {
try (InputStream is = Files.newInputStream(Paths.get("C://Temp/xx.xml"))) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document xml = builder.parse(new InputSource(is));
NodeList rootNodes = xml.getElementsByTagName("jobs");
Node rootNode = rootNodes.item(0);
Element rootElement = (Element) rootNode;
NodeList jobsList = rootElement.getElementsByTagName("job");
System.out.println("list before removal");
for (int i = 0; i < jobsList.getLength(); i++) {
Node job = jobsList.item(i);
Element jobElement = (Element) job;
System.out.println(jobElement.getAttribute("id"));
}
for (int i = 0; i < jobsList.getLength(); i++) {
Node job = jobsList.item(i);
Element jobElement = (Element) job;
if (jobElement.getAttribute("id").equals("1")) {
rootNode.removeChild(job);
}
}
System.out.println("list after removal");
jobsList = rootElement.getElementsByTagName("job");
for (int i = 0; i < jobsList.getLength(); i++) {
Node job = jobsList.item(i);
Element jobElement = (Element) job;
System.out.println(jobElement.getAttribute("id"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
output:
list before removal
1
2
list after removal
2
This is my java code:
class SentenceNode {
Node xscope;
Node cue;
}
List<SentenceNode> getSentenceNodes(InputSource is) {
List<SentenceNode> sentenceNodes = new ArrayList<SentenceNode>();
try {
Object xscopes = XPathFactory
.newInstance()
.newXPath()
.evaluate("//xscope/cue", is,
XPathConstants.NODESET);
if (xscopes != null) {
NodeList cuesNodes = (NodeList) xscopes;
for (int i = 0; i < cuesNodes.getLength(); i++) {
SentenceNode sentenceNode = new SentenceNode();
Node cue = cuesNodes.item(i);
sentenceNode.cue = cue;
NodeList xscope = cue.getParentNode().getParentNode()
.getChildNodes();
for (int j = 0; j < xscope.getLength(); j++) {
Node n = xscope.item(j);
if (n.getNodeName().equals("xscope")) {
sentenceNode.xscope = n;
break;
}
}
sentenceNodes.add(sentenceNode);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return sentenceNodes;
}
public void displaySentenceNodes() throws ClassNotFoundException, ClassCastException,
IOException {
InputSource is = new InputSource(new StringReader("TestBIO.xml"));
List<SentenceNode> nodes = getSentenceNodes(is);
for (SentenceNode node : nodes) {
System.out.println("Xscope: " + node.xscope.getTextContent());
System.out
.println("Cue: " + node.cue.getTextContent());
}
I want to extract from this xml the sentence with its cue and xscope.For each sentence I want to obtain the xscope and cue.If the sentence has more xscopes and more cues I want to obtain all.
Here is my xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Annotation created="22/2/2010" creator="BioscopeWriterCasConsumer">
<DocumentSet>
<Document type="Biological_abstract">
<DocID type="PMID">1984449</DocID>
<DocumentPart type="AbstractText">
<sentence>When cells were infected with HIV, no induction of NF-KB factor was detected, <xscope>whereas high level of progeny virions was produced, <cue>suggesting</cue> that</xscope>.</sentence>
<sentence> HIV <xscope><cue>could</cue> mimic some differentiation/activation stimuli allowing nuclear NF-KB expression</xscope>.</sentence>
</DocumentPart>
</Document>
</DocumentSet>
</Annotation>
An error occured when I am trying to parse the xml file.
[Fatal Error] :1:1: Content is not allowed in prolog.
org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog.
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.evaluate(Unknown Source)
You are missing ? Character in xml. Should start:
<?xml version="
I found the equivalent.Is like XPath but parse the xml with DOM parser bottom-up
Here is the code:
class SentenceNode {
Node xscope;
Node cue;
}
List<SentenceNode> extractElem(String file) throws ParserConfigurationException,
SAXException, IOException {
List<SentenceNode> sentenceNodes = new ArrayList<SentenceNode>();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse("Test1.xml");
document.getDocumentElement().normalize();
NodeList nList = document.getElementsByTagName("cue");
for (int temp = 0; temp < nList.getLength(); temp++) {
SentenceNode sentNode = new SentenceNode();
Node nodeCue = nList.item(temp);
sentNode.cue = nodeCue;
NodeList xscope = null;
if(nodeCue.getParentNode().getParentNode().getNodeName().equals("sentence")){
xscope = nodeCue.getParentNode().getParentNode()
.getChildNodes();
}
else if(nodeCue.getParentNode().getParentNode().getNodeName().equals("xscope")){
xscope = nodeCue.getParentNode().getParentNode().getParentNode()
.getChildNodes();
}
for (int j = 0; j < xscope.getLength(); j++) {
Node n = xscope.item(j);
if (n.getNodeName().equals("xscope")) {
sentNode.xscope = n;
break;
}
}
sentenceNodes.add(sentNode);
}
return sentenceNodes;
}
And it worked
I am trying to read in a file path from an XML file in java, but I am getting a file not found exception. I am not sure how to fix this. Any help would be appreciated.
This is the XML file:
<adapters>
<adapter>
<class>adapters.CSVFileAdapter</class>
<properties>
<property name="filename">C:\test.csv</property>
</properties>
</adapter>
<adapter>
<class>adapters.SNMPAdapter</class>
<properties>
<property name="target">10.100.85.135</property>
<property name="port">134</property>
</properties>
</adapter>
</adapters>
This is my java code:
public class XMLConfigurationReader {
public static List<String> load()
{
List<String> adpList = new ArrayList<String>();
try{
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse (new File("C:/myProject/adapters.xml"));
doc.normalize();
NodeList rootNodes = doc.getElementsByTagName("adapters");
Node rootNode = rootNodes.item(0);
Element rootElement = (Element) rootNode;
rootNodes = rootElement.getElementsByTagName("class");
for(int k=0; k<rootNodes.getLength(); k++){
Node theAdapter = rootNodes.item(k);
Element adpElement = (Element) theAdapter;
adpList.add(adpElement.getTextContent());
}
rootNodes = doc.getElementsByTagName("properties");
for (int i = 0; i < rootNodes.getLength(); i++) { // loop for properties
Node nodeData = rootNodes.item(i);
Element elementColumnDetails = (Element) nodeData;
NodeList nodeListRow = elementColumnDetails.getElementsByTagName("property");
for (int j = 0; j < nodeListRow.getLength(); j++) { // loop for property
Node nodeRow = nodeListRow.item(j);
Element elementRow = (Element) nodeRow;
if(elementRow.getAttribute("property") != null){
String property = elementRow.getTextContent().trim();
}
}
}
}catch(ParserConfigurationException e){
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return adpList;
}
}
Problem with your code is in this line
adaptersList.item(0).getChildNodes().item(0).getNodeValue();
it should be replaced with
adaptersList.item(0).getTextContent();
in order to give you that pathname.
Firstly to read a file:
public class FileRead {
static String string = File.separator;
public static void main(String[] args) {
File file = new File("C:"+string+"myProject"+string+"adapters.xml");
System.out.println(file.getName());
}
}
Then try to test below code will help you to get file Name from xml:
NodeList nodeListData = xmlTableName.getElementsByTagName("properties");
for (int k = 0; k < nodeListData.getLength(); k++) { // loop for properties
Node nodeData = nodeListData.item(k);
Element elementColumnDetails = (Element) nodeData;
NodeList nodeListRow = elementColumnDetails.getElementsByTagName("property);
for (int l = 0; l < nodeListRow.getLength(); l++) { // loop for property
Node nodeRow = nodeListRow.item(l);
Element elementRow = (Element) nodeRow;
if(elementRow.getAttribute("filename")){
filePath = elementRow.getTextContent().trim();
}
}
}
I have xml file
<A>
<A1>
<A2>Hi</A2>
</A1>
<A>
<B>
<B1></B1>
<B2>100</B2>
</B>
<A>
<A1>
<A2>Hello</A2>
</A1>
<A>
<B>
<B1>1000</B1>
<B2></B2>
</B>
likewise this goes more than 10 blocks. Now my java code able to read one by one that is first reads all after that reads tag.
Code:
public class XMLParse {
static Document doc;
public static void main(String argv[]) {
try {
File file = new File("/home/dev042/Desktop/xxx.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(file);
doc.getDocumentElement().normalize();
System.out.println("Root element " + doc.getDocumentElement().getNodeName());
NodeList nodeLst = doc.getElementsByTagName("A");
System.out.println("Information of all Balence Sheet");
int count = nodeLst.getLength();
String name;
for (int s = 0; s < nodeLst.getLength(); s++) {
Node fstNode = nodeLst.item(s);
if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
Element fstElmnt = (Element) fstNode;
NodeList fstNmElmntLst = fstElmnt.getElementsByTagName("A1");
for(int i =0; i < fstNmElmntLst.getLength(); i++ )
{
Node lst = fstNmElmntLst.item(i);
if(lst.getNodeType() == Node.ELEMENT_NODE)
{
Element fsttravel = (Element) lst;
NodeList secNmElt = fsttravel.getElementsByTagName("*");
name = secNmElt.item(0).getTextContent();
System.out.println("Name : " + name);
}
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
String amt;
double amount;
NodeList nodeLst = doc.getElementsByTagName("B");
int coun = nodeLst.getLength();
for (int s = 0; s < nodeLst.getLength(); s++) {
Node secNode = nodeLst.item(s);
if (secNode.getNodeType() == Node.ELEMENT_NODE) {
try
{
Element amtval = (Element) secNode;
NodeList secval = amtval.getElementsByTagName("B1");
amt = secval.item(0).getTextContent();
//amount = Double.parseDouble(amt);
System.out.println("SubAmt :" + amt);
NodeList lstNmElmntLst = amtval.getElementsByTagName("B2");
amt = lstNmElmntLst.item(0).getTextContent();
System.out.println("MainAmt : " +amt);
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
}
}
current output:
Hi
Hello
100
1000
I want to read the tags alternatively. then only i can able map the values. How can i read these tags alternatively. output should be like this
Hi 100
Hello 1000
Kindly help me out of it.
Thanks in advance..
I think you need to filter only tags so that your parser will fetch only tags.For this you can use XPath.This is an examples here:
http://www.roseindia.net/tutorials/xPath/java-xpath.shtml
I have a simple XML file
<requirements>
<requirement>
<name> SwitchON</name>
<id>1</id>
<text>The Light shall turn on when the Switch is on.</text>
</requirement>
<requirement>
<name>SwitchOFF</name>
<id>2</id>
<text>The Light shall turn off when the Switch is off.</text>
</requirement>
<requirement>
<name>Lightbulb</name>
<id>3</id>
<text>The Light bulb shall be connected </text>
</requirement>
<requirement>
<name>Power</name>
<id>4</id>
<text>The Light shall have the power supply</text>
</requirement>
</requirements>
I am trying to show the information in this file in a table model.
I have a method (readFromXMl) that reads the XML file and returns a table model.
public static RequirementTable readFromXMl(String fileName) {
RequirementTable T = new RequirementTable();
Requirement R = new Requirement();
try {
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new File(fileName));
doc.getDocumentElement().normalize();
NodeList listOfRequirements = doc.getElementsByTagName("requirement");
int test = listOfRequirements.getLength();
System.out.println("Total no of people : " + test);
for (int i = 0; i < listOfRequirements.getLength(); i++) {
Node RequirementNode = listOfRequirements.item(i);
if (RequirementNode.getNodeType() == Node.ELEMENT_NODE) {
Element RequirementElement = (Element) RequirementNode;
NodeList IdList = RequirementElement.getElementsByTagName("id");
Element IdElement = (Element) IdList.item(0);
NodeList textIdList = IdElement.getChildNodes();
R.setId(Integer.parseInt(textIdList.item(0).getNodeValue()));
NodeList DescriptionList = RequirementElement.getElementsByTagName("text");
Element DescriptionElement = (Element) DescriptionList.item(0);
NodeList textDescriptionList = DescriptionElement.getChildNodes();
R.setText(textDescriptionList.item(0).toString());
NodeList NameList = RequirementElement.getElementsByTagName("name");
Element NameElement = (Element) NameList;
NodeList textNameList = NameElement.getChildNodes();
if (textNameList.item(0).toString().equals("SwitchON")) {
T.addRequirement((SwitchOnReq)R);
} else if (textNameList.item(0).toString().equals("SwitchOFF")) {
T.addRequirement((SwitchOFFReq)R);
} else if (textNameList.item(0).toString().equals("LightBulb")) {
T.addRequirement((BulbRequirement)R);
} else if (textNameList.item(0).toString().equals("Power")) {
T.addRequirement((PowerRequirement)R);
}
}
}
} catch (SAXParseException err) {
System.out.println("** Parsing error" + ", line " + err.getLineNumber() + ", uri " + err.getSystemId());
System.out.println(" " + err.getMessage());
} catch (SAXException e) {
Exception x = e.getException();
((x == null) ? e : x).printStackTrace();
} catch (Throwable t) {
t.printStackTrace();
}
return T;
}
However in this line I am getting an error which says the the pointer is null
Element IdElement = (Element) IdList.item(0); IdElement is null!!
Instead of all the looping and other xml ugliness, let me suggest a little helper method:
private static String getNodeValue(Node n, String path)
throws XPathExpressionException {
XPath xpath = XPathFactory.newInstance().newXPath();
return (String) xpath.evaluate(path, n, XPathConstants.STRING);
}
Use like this:
for (int i = 0; i < listOfRequirements.getLength(); i++) {
Node RequirementNode = listOfRequirements.item(i);
System.out.println("name:" + getNodeValue(RequirementNode, "name"));
System.out.println("id:" + getNodeValue(RequirementNode, "id"));
System.out.println("text:" + getNodeValue(RequirementNode, "text"));
...
to get all the values and set your requirements.