How do I get relevant information from a JSON output? - java

I am trying to parse an XML file into JSON. While I am able to parse successfully using a HashMap, the XML file I am using has a lot of irrelevant information which also gets reflected in the JSON.
My XML file is a topology file, basically topology for network elements and their respective processes. So, it is divided into parent and child nodes. Most of the relevant information I seek lie with the parent nodes and I want to disregard the child nodes by whatever means, so that only the parent nodes are available in the JSON.
Here's the code I wrote to parse. I have tried to write code to get child enter code herenodes but I can't figure out how to remove them(like what conditions I can use):
static String nodeType1,nodeType;
static String nodeName1,nodeName;
static String nodeIP1,nodeIP;
public static void main(String[] args) {
try { File fXmlFile = new File("SystemTopology.txt");
DocumentBuilderFactory dbFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("SNOSNE") ;
Map<String, Object> data = new HashMap<String, Object>();
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
Element el = (Element) nNode;
nodeType = el.getAttribute("snostype");
nodeName = el.getAttribute("cimname");
nodeIP = el.getAttribute("snoshostip");
NodeList list = el.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node nNode1 = list.item(i);
if(list.item(i).getNodeType() == Node.ELEMENT_NODE){
Element element = (Element) list.item(i);
nodeType1 = element.getAttribute("snostype");
nodeName1 = element.getAttribute("cimname");
nodeIP1 = element.getAttribute("snoshostip");
if(!nodeIP1.isEmpty()) {
System.out.println(nodeType1);
System.out.println(nodeName1);
System.out.println(nodeIP1);
}
}
}
//Need to add conditions here that would get only child nodes
if(!nodeIP.isEmpty()) {
data.put(nodeName, nodeType+","+nodeIP);
}
}
JSONObject json = new JSONObject(data);
System.out.printf( "JSON: %s", json.toString(2));
}
catch (Exception excp)
{
System.out.println("topology file not found " + excp.getMessage());
}
Topology file looks like:
<SNOSNE cimname="EDA_01" snoshostip="1.1.1.1" snostype="EDA">
<SNOSNE cimname="Resources" snoshostip="1.1.1.1" snostype="EDA">
</SNOSNE>
<SNOSNE cimname="CPU" snoshostip="1.1.1.1" snostype="EDA">
</SNOSNE>
...
...
...
</SNOSNE>
Expected output needs to contain only the parent with cimname="EDA_01". And all child nodes need to be disregarded in JSON output.

Related

Java get tag name of a Node

I need to read a small xml file and validate it's content against a hardcoded HashMap with key= tag and value= text inside tag.
I can not get the tag name of the Node.
If I convert the Node to Element I get a cast exception.
I am reading using the DOOM classes:
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
NodeList list = doc.getElementsByTagName("MergeOptions");
if (list.getLength() == 0)
{
//throw
}
NodeList config = list.item(0).getChildNodes();
for (int i = 0; i <= config.getLength() - 1; i++)
{
Node setting = config.item(i);
String nodeName = setting.getNodeValue();
String value = setting.getTextContent();
if (defaultMergeOptions.containsKey(nodeName) == false)
{
//throw
}
if (defaultMergeOptions.get(nodeName).equals(value))
{
//throw
}
Xml file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<MergeOptions>
<sometagName>false</sometagName>
</MergeOptions>
I am helping you with the following code structure. Once you see the tag name and the value, you can apply the logic to compare from HashMap key or value.
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;
public class Test1 {
public static void main(String[] args) throws Exception {
String xmlFile = "test.xml";
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
Element root = doc.getDocumentElement();
System.out.println(root.getNodeName());
NodeList list = root.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE)
{
System.out.println(node.getNodeName() + " : " + node.getTextContent());
}
}
}
}
I have tried to run your code, it works fine, no class cast exceptions.
Note how I used the element in the for loop the get the name, value or the existsnce of a possible children.
final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
"<MergeOptions>\n<sometagName>false</sometagName>\n</MergeOptions>";
final InputStream xsmlStream = new ByteArrayInputStream(xml.getBytes());
final DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
final DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
final Document doc = dBuilder.parse(xsmlStream);
final NodeList nodes = doc.getElementsByTagName("MergeOptions");
for (int i = 0; i < nodes.getLength(); i++) {
final Element element = (Element) nodes.item(i);
System.out.println(element.hasChildNodes());
System.out.println(element.getNodeValue());
System.out.println(element.getTagName());
}
Using hash map is with node names as keys is a bit tricky, 'cause if your XML file have multiple node names with same names and different values, the HashMap will only store only one unique keys thus validate only one of the same name nodes. The other same name nodes but with different values will be not valid.
Well I did something diffrent.
Seems to work:
IntegrationTest.getInstance().getLogger().log(Level.INFO, "Reading merge-que file: " + xmlFile.getAbsolutePath());
try
{
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xmlFile);
for (Entry<String, String> entry : defaultMergeOptions.entrySet())
{
String tagName = entry.getKey();
NodeList list = doc.getElementsByTagName(tagName);
if (list.getLength() != 1)
{
IntegrationTest.getInstance().getLogger().log(Level.SEVERE, TestResult.FAIL, "Merge option [{0}] has invalid content. Tag [{1}] missing or to many",
new Object[] { xmlFile.getName(), tagName });
result = TestResult.FAIL;
continue;
}
if (!defaultMergeOptions.get(tagName).equals(list.item(0).getTextContent()))
{
IntegrationTest.getInstance().getLogger().log(Level.WARNING, TestResult.FAIL, "Merge option [{0}] has diffrent content for tag [{1}].",
new Object[] { xmlFile.getCanonicalPath(), tagName });
result = TestResult.FAIL;
}
}
}
catch (Exception e)
{
IntegrationTest.getInstance().getLogger().log(Level.SEVERE, SBUtil.stackTraceToString(e.getStackTrace()));
throw new IntegrationTestException(e);
}
}

How to get data from XML node?

I am struggling to get the data out of the following XML node. I use DocumentBuilder to parse XML and I usually get the value of a node by defining the node but in this case I am not sure how the node would be.
<Session.openRs status="success" sessionID="19217B84:AA3649FE:B211FF37:E61A78F1:7A35D91D:48E90C41" roleBasedSecurity="1" entityID="1" />
This is how I am getting the values for other tags by the tag name.
public List<NYProgramTO> getNYPPAData() throws Exception {
this.getConfiguration();
List<NYProgramTO> to = dao.getLatestNYData();
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document document = null;
// Returns chunkSize
/*List<NYProgramTO> myList = getNextChunk(to);
ExecutorService executor = Executors.newFixedThreadPool(myList.size());
myList.stream().parallel()
.forEach((NYProgramTO nyTo) ->
{
executor.execute(new NYExecutorThread(nyTo, migrationConfig , appContext, dao));
});
executor.shutdown();
executor.awaitTermination(300, TimeUnit.SECONDS);
System.gc();*/
try {
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource source = new InputSource();
for(NYProgramTO nyProgram: to) {
String reqXML = nyProgram.getRequestXML();
String response = RatingRequestProcessor.postRequestToDC(reqXML, URL);
// dao.storeData(nyProgram);
System.out.println(response);
if(response != null) {
source.setCharacterStream(new StringReader(response));
document = builder.parse(source);
NodeList list = document.getElementsByTagName(NYPG3Constants.SERVER);
for(int iterate = 0; iterate < list.getLength(); iterate++){
Node node = list.item(iterate);
if(node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) node;
nyProgram.setResponseXML(response);
nyProgram.setFirstName(element.getElementsByTagName(NYPG3Constants.F_NAME).item(0).getTextContent());
nyProgram.setLastName(element.getElementsByTagName(NYPG3Constants.L_NAME).item(0).getTextContent());
nyProgram.setPolicyNumber(element.getElementsByTagName(NYPG3Constants.P_NUMBER).item(0).getTextContent());
nyProgram.setZipCode(element.getElementsByTagName(NYPG3Constants.Z_CODE).item(0).getTextContent());
nyProgram.setDateOfBirth(element.getElementsByTagName(NYPG3Constants.DOB).item(0).getTextContent());
nyProgram.setAgencyCode(element.getElementsByTagName(NYPG3Constants.AGENCY_CODE).item(0).getTextContent());
nyProgram.setLob(element.getElementsByTagName(NYPG3Constants.LINE_OF_BUSINESS).item(0).getTextContent());
if(element.getElementsByTagName(NYPG3Constants.SUBMISSION_NUMBER).item(0) != null){
nyProgram.setSubmissionNumber(element.getElementsByTagName(NYPG3Constants.SUBMISSION_NUMBER).item(0).getTextContent());
} else {
nyProgram.setSubmissionNumber("null");
}
I need to get the value for sessionId. What I want to know is the node, I am sure it can't be .I am retrieving the values via tag names so what would be the tag name in this case?
Thanks in advance
You should consider using XPath. At least for me, is so much easy to use and, in your case, in order to get sessionID you could try something like this:
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "/Session.openRs/#sessionID";
String sessionID = xPath.evaluate(expression,document);
You can obtain 'document' like this:
Document document = builder.newDocumentBuilder();
Hope this can help!!

Java XML Parsing into a List and Grabbing Nodes

I am parsing an XML document and I need to put every child in to a List and then once it is in a List I need to be able to grab a specific child node from an index in the List. My code so far only grabs every child node but I don't know how to put it in a List, looping through it doesn't seem to work. Here is what I have so far:
public static void main(String[] args){
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
URL url = new URL ("http://feeds.cdnak.neulion.com/fs/nhl/mobile/feeds/data/20140401.xml");
URLConnection connection = url.openConnection();
InputStream is = connection.getInputStream();
// use the factory to create a documentbuilder
DocumentBuilder builder = factory.newDocumentBuilder();
// create a new document from input stream
Document doc = builder.parse(is); // get the first element
Element element = doc.getDocumentElement();
System.out.println(element);
// get all child nodes
NodeList nodes = element.getChildNodes();
// print the text content of each child
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println("" + nodes.item(i).getTextContent());
} } catch (Exception ex) {
ex.printStackTrace();
}
}

How to retrieve XML including tags using the DOM parser

I am using org.w3c.dom to parse an XML file. Then I need to return the ENTIRE XML for a specific node including the tags, not just the values of the tags. I'm using the NodeList because I need to count how many records are in the file. But I also need to read the file wholesale from the beginning and then write it out to a new XML file. But my current code only prints the value of the node, but not the node itself. I'm stumped.
public static void main(String[] args) {
try {
File fXmlFile = new File (args[0]);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
NodeList listOfRecords = doc.getElementsByTagName("record");
int totalRecords = listOfRecords.getLength();
System.out.println("Total number of records : " + totalRecords);
int amountToSplice = queryUser();
for (int i = 0; i < amountToSplice; i++) {
String stringNode = listOfRecords.item(i).getTextContent();
System.out.println(stringNode);
}
} catch (Exception e) {
e.printStackTrace();
}
}
getTextContent() will only "return the text content of this node and its descendants" i.e. you only get the content of the 'text' type nodes. When parsing XML it's good to remember there are several different types of node, see XML DOM Node Types.
To do what you want, you could create a utility method like this...
public static String nodeToString(Node node)
{
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
t.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter sw = new StringWriter();
t.transform(new DOMSource(node), new StreamResult(sw));
return sw.toString();
}
Then loop and print like this...
for (int i = 0; i < amountToSplice; i++)
System.out.println(nodeToString(listOfRecords.item(i)));

How to parse this XML in Android?

I am quite new to XML parsing and I have my method of parsing XML. Only that method is for simple XML layouts with just 1 child node.
I now have to parse an XML file with childs that have childs that have childs (got it :)?)
This is the parse-method I have now:
protected Map<String, Maatschappij> getAutopechTel() {
Map<String, Maatschappij> telVoorAutopech = new HashMap<String, Maatschappij>();
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
Document doc = builder.parse(getAssets().open("autopech.xml"));
NodeList nl = doc.getElementsByTagName("dienst");
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
Maatschappij maat = new Maatschappij();
maat.setNaam(Xml.innerHtml(Xml.getChildByTagName(node, "naam")));
maat.setTel(Xml.innerHtml(Xml.getChildByTagName(node, "tel")));
telVoorAutopech.put(maat.getTel(), maat);
}
} catch (Exception e) {
}
return telVoorAutopech;
}
How must I adjust this in order to parse this type of XML file:
<Message>
<Service>Serviceeee</Service>
<Owner>Bla</Owner>
<LocationFeedTo>Too</LocationFeedTo>
<Location>http://maps.google.com/?q=52.390001,4.890145</Location>
<Child1>
<Child1_1>
<Child1_1_1>ANWB</Child1_1_1>
</Child1_1>
</Child1>
<Message>
You can use SAXParser to parse XML in Android :
Here is a detailed tutorial with example and also another one here by IBM developerWorks.
DOM Parser is slow and consume a lot
memory if it load a XML document
which contains a lot of data. Please
consider SAX parser as solution for
it, SAX is faster than DOM and use
less memory.
Try this one out but I haven't tested this code yet. It recursively traverses all the nodes and adds which are ELEMENT_NODE to the Vector<Node>.
public void traverseNodes(Node node, Vector<Node> nodeList)
{
if(node.getNodeType() == Node.ELEMENT_NODE)
{
nodeList.add(node);
if(node.getChildNodes().getLength() >= 1)
{
NodeList childNodeList = node.getChildNodes();
for(int nodeIndex = 1;nodeIndex < childNodeList.getLength(); nodeIndex++)
{
traverseNodes(childNodeList.item(nodeIndex),nodeList);
}
}
}
}

Categories

Resources