AAppend an element to the root - java

I'm trying to append a tag to the roo of my xml file, however I'm getting an error on createElement :
if(hashValidationRulesAtt.get("mandatory").equals("true") && (elemValue==null||elemValue.equals(""))){
DOCUMENTS.appendChild(doc.createElement(statusKO));}
else{
DOCUMENTS.appendChild(doc.createElement(statusOK));
}. Any help
if(hashValidationRulesAtt.get("mandatory").equals("true") && (elemValue==null||elemValue.equals(""))){
DOCUMENTS.appendChild(doc.createElement(statusKO));}
else{
DOCUMENTS.appendChild(doc.createElement(statusOK));
}

You should append the root element to the document and then append the childelements of the root to the root element.
Here is a bit of an example
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("Expenses");
doc.appendChild(rootElement);
for (String s : list)
{
Element element = doc.createElement(type);
element.appendChild(doc.createTextNode(s));
rootElement.appendChild(element);
}

Related

Tag names are missing in the XML parsed except the root element

I am reading a dynamic XML file (without any known structure) and putting the relevant tag name and value to a hashmap (ex: metadata<tagName, Value> ).
My issue here is, I can not get the tagName but it only adds the root tagName and all the values of entire xml.
my XML is:
<?xml version="1.0" encoding="UTF-8"?>
<form kwf="VARA">
<sec1>
<docID>2d2c5bf209b79d8b1a1f840ce4ce4030e66a76d6</docID>
<qrCode>xx.jpg</qrCode>
<title>NOOO FORM NAME</title>
<ELO_VARAFNAME>NO</ELO_VARAFNAME>
<ELO_VARALNAME>NAME</ELO_VARALNAME>
<ELO_VARAEMAIL>noname#gmail.com</ELO_VARAEMAIL>
<ELO_VARAORBEONDOCID>2d2c5bf209b79d8b1a1f840ce4ce4030e66a76d6</ELO_VARAORBEONDOCID>
</sec1>
</form>
My Code is:
public static Map<String,String> getMetaDataFromOrbeonXML(File fXmlFile) throws SAXException, ParserConfigurationException, IOException
{
Map metaData = new HashMap();
String formName="";
String docID = "";
try {
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("form");
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;
docID = eElement.getElementsByTagName("docID").item(0).getTextContent();
metaData.put("docID", docID);
metaData.put("appName", APP_NAME);
metaData.put(eElement.getTagName(), eElement.getTextContent());
System.out.println("META DATA MAP: "+ metaData.toString());
}
}
} catch (Exception e) {
e.printStackTrace();
}
return metaData;
}
And the out put is:
{form= 2d2c5bf209b79d8b1a1f840ce4ce4030e66a76d6
xx.jpg
NOOO FORM NAME
NO
NAME
noname#gmail.com
2d2c5bf209b79d8b1a1f840ce4ce4030e66a76d6
, docID=2d2c5bf209b79d8b1a1f840ce4ce4030e66a76d6, appName=VIRGINAUSI, formName=AITSLForm}
Tag names are missing in the map except the root element. Please help !
The code above correctly adds 2 entries in the map. The first entry, maps element Form to it's text content (which is the collection of the text content of all it's descendant nodes).
If you want to access the descendant nodes you'll need to use eElement.getChildNodes() and iterate over the NodeList returned.
This might be useful:
Java: Most efficient method to iterate over all elements in a org.w3c.dom.Document?

JDOM removing a element from root

I am not able to remove an element from root element. Below is the example of xml
<ADMIN-DATA>
<DATA-DECLARATION ID="Hi"> </DATA-DECLARATION>
<DATA ID="Hi">
<DATA-DECLARATION-REF ID-REF="Hi"> </DATA-DECLARATION-REF>
<DATA ID="Hi">
<DATA-DECLARATION ID="Delete"> </DATA-DECLARATION>
</DATA>
</DATA>
</ADMIN-DATA>
I want to delete
<DATA-DECLARATION ID="Delete"> </DATA-DECLARATION>
JDOM Code below
Element root = document.getRootElement();
String id = null;
boolean check = false;
String idRef = null;
ElementFilter filter = new org.jdom2.filter.ElementFilter(
"DATA-DECLARATION");
ElementFilter filter2 = new org.jdom2.filter.ElementFilter(
"DATA-DECLARATION-REF");
for (Element dataDecId : root.getDescendants(filter))
{
check = false;
id = dataDecId.getAttributeValue("ID");
for (Element dataDecIdRef : root.getDescendants(filter2))
{
idRef = dataDecIdRef.getAttributeValue("ID-REF");
if (null != idRef && idRef.equalsIgnoreCase(id))
{
check = true;
break;
}
}
if (!check)
{
root.removeContent(dataDecId);
}
}
Above root.removeContent(dataDecId); is not working. Correct me.
Note that <DATA-DECLARATION ID="Delete"> </DATA-DECLARATION> is not a child of the root element.... it's a child of a DATA element which in turn is a child of a DATA element which finally is a child of the ADMIN-DATA element.
You cannot ask the root element to remove DATA-DECLARATION ID="Delete" because it is not a direct child.
Note that the child itself knows it's location, so, the simpler way to do it, is to change root.removeContent(dataDecId) to be just dataDecId.detach()
Well, to me it looks like there are some errors in the .xml file. You're trying to get the ID-REF field whereas Delete only has an ID.
Moreover, I doubt that your XML file is correct considering you have a typo here:
<DATA-DECLARATION-REF ID-REF="Hi"> </ATA-DECLARATION-REF>
and two different tags here:
<DATA-DECLARATION ID="Delete"> </DATA-DECLARATION-REF>.
Another way:
XPATH combines tag and values in a clear way:
XPath xPath = XPathFactory.newInstance().newXPath();
String expression="//DATA-DECLARATION[#ID='Delete']"; // self-explained
NodeList nodes = (NodeList) xPath.compile(expression).evaluate(document, XPathConstants.NODESET);
for(int i=0; i<nodes.getLength(); i++)
{
Node the_node = nodes.item(i);
if(the_node instanceof Element)
{
Element the_element=(Element) the_node;
// FATHER
Node father=the_node.getParentNode();
// SUPPRESSION
father.removeChild(the_node);
// First one only ?
break;
}
}

Couldn't able to read the attribute using DOM parser

i am having issues when reading the attribute of a link,
this is the structure of my xml,
<entry>
<updated>
<title>
<link href="">
</entry>
i managed to read the date and title correctly but the href attribute of the link is not working.
Here is my code,
NodeList nList = doc.getElementsByTagName("entry");
System.out.println("============================");
for (int temp = 0; temp < nList.getLength(); temp++)
{
Node node = nList.item(temp);
System.out.println(""); //Just a separator
if (node.getNodeType() == Node.ELEMENT_NODE)
{
Element eElement = (Element) node;
System.out.println("Date : " + eElement.getElementsByTagName("updated").item(0).getTextContent());
System.out.println("Title : " + eElement.getElementsByTagName("title").item(0).getTextContent());
// The below code is for reading href attribute of link,
NodeList node1 = eElement.getElementsByTagName("link");
Element eElement1 = (Element) node1;
System.out.println(eElement1.getAttribute("href"));
}
}
I am creating a new nodelist for the attributes of link but the code is not working.
error:
java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl cannot be cast to org.w3c.dom.Element
at Demo.main(Demo.java:45)
A NodeList is not an Element and cannot be cast to one (successfully), so this code isn't going to work:
NodeList node1 = eElement.getElementsByTagName("link");
Element eElement1 = (Element) node1;
A NodeList is, as the name suggests, a list of nodes (and in your case, the nodes will be Elements). So this code would work for the first link:
NodeList list = eElement.getElementsByTagName("link");
Element eElement1 = (Element) list.item(0);
...whereupon your getAttribute should work fine, as Element has getAttribute.
Side note: If your library has support for newer query functions, you could also do this:
String href = ((Element)eElement.querySelector("entry")).getAttribute("href");
...because querySelector returns just the first match (not a list) (or null if no matches; if that's a possibility, add a guard to the above). But I don't know how well querySelector is supported outside of browsers yet.
// The below code is for reading href attribute of link,
NodeList node1 = eElement.getElementsByTagName("link");
Element eElement1 = (Element) node1;
NodeList will give you Node object not Element, you can get href value as follows,
String hrefValue = nodeList.item(0).
getAttributes().getNamedItem("href").getNodeValue();

List of elements in JDOM

I have a question regarding list of elements in xml
I am trying to delete everything under and also the tags.
But when I debug my list of param I noticed my list looks like this :
text
element
text
element
text
element
text
element
But I want only the elements in the list and not the text so I can more easily delete the correct element.
How to do this?
This is my code :
public void deleteParameter(int row, int index) {
int objTypeIndex = index + 1;
File xml = new File(XMLEditorService.getXMLEditorService().getFile());
try {
XMLOutputter xmlOut = new XMLOutputter();
org.jdom2.Document doc = new SAXBuilder().build(xml);
Namespace ns = Namespace.getNamespace("http://www.xxx.com");
org.jdom2.Element rootNode = doc.getRootElement();
org.jdom2.Element typeContent = rootNode.getChildren().get(
objTypeIndex);
List<Element> list = typeContent.getChildren("param", ns);
if (list.size() > 0) {
Element element = list.get(row); //remove correct element
element.removeContent();
System.out.println("element removed: " + element.getName());
xmlOut.setFormat(Format.getPrettyFormat());
xmlOut.output(doc, new FileWriter(XMLEditorService
.getXMLEditorService().getFile()));
}
} catch (IOException io) {
System.out.println(io.getMessage());
} catch (JDOMException jdomex) {
System.out.println(jdomex.getMessage());
}
}
The list i am refering to is this line : List<Element> list = typeContent.getChildren("param", ns);
The method call: element.removeContent(); does not remove the Element from its parent, but instead it removes all content from the element (makes it empty).
You probably just want to do: element.detach(); instead.... which will remove the Element (and as a result all of its content too) from the document.
You could use a JDOM2 filter to get elements of a specific type.
Look at This example to see how to retrieve specific elements of the XML using Filters in JDOM2.

Building DOM document from xml string gives me a null document

I'm trying to use the DOM library to parse a string in xml format. For some reason my document contains nulls and I run into issues trying to parse it. The string variable 'response' is not null and I am able to see the string when in debug mode.
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(response));
Document doc = builder.parse(is);
NodeList nodes = doc.getElementsByTagName("BatchFile");;
for (int i = 0; i < nodes.getLength(); i++) {
Element element = (Element) nodes.item(i);
NodeList batchItem = element.getChildNodes();
String uri = batchItem.item(0).getNodeValue();
String id = batchItem.item(1).getNodeValue();
String fqName = batchItem.item(2).getNodeValue();
}
Highlighting over the line Document doc = builder.parse(is); after it has run shows the result of [#document: null].
Edit: I've managed to not got an empty doc now but the string values are still null (at end of code). How would I get the value of something like this
<GetBatchFilesResult>
<BatchFile>
<Uri>uri</Uri>
<ID>id</ID>
<FQName>file.zip</FQName>
</BatchFile>
</GetBatchFilesResult>
You can also use getTextContent(). getNodeValue will return null for elements. Besides, you'd better use getElementsByTagName, since white spaces are also treated as one of the child nodes.
Element element = (Element) nodes.item(i);
String uri = element.getElementsByTagName("Uri").item(0).getTextContent();
String id = element.getElementsByTagName("ID").item(0).getTextContent();
String fqName = element.getElementsByTagName("FQName").item(0).getTextContent();
Check Node API document to see what type of nodes will return null for getNodeValue.
I found the solution. Seems stupid that you have to do it this way to get a value from a node.
Element element = (Element) nodes.item(i);
NodeList batchItem = element.getChildNodes();
Element uri = (Element) batchItem.item(0);
Element id = (Element) batchItem.item(1);
Element fqName = (Element) batchItem.item(2);
NodeList test = uri.getChildNodes();
NodeList test1 = id.getChildNodes();
NodeList test2 = fqName.getChildNodes();
String strURI= test.item(0).getNodeValue();
String strID= test1.item(0).getNodeValue();
String strFQName= test2.item(0).getNodeValue();

Categories

Resources