Transform linkedhashmap into org.w3c.dom.Element - java

I need to create a method that given any LinkedHashMap , this method have to transform it into XML/Dom elements of a Document like :
#Override
public Element marshal(Object linkedHashMap) {
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
final Element element = doc.createElement("root");
//For each attribute and object of the linked hashmap
// I must iterate recursively in order to get all the objects and atributes of the LinkedHashMap and append them to the root node element:
//element.appendChild(...));
return element; // here the element must be already populated with all the attributes of the linked hashmap and its values.
}
I have no idea about how can I achieve this , how can I loop through the attributes of a LinkedHashMap in order to map them to Element ?
I need something like this , but it must iterate over all the levels and sublevels (nested linkedhashmap objects) of the linkedhashmap:
private void marshalMapElements(ArrayList<LinkedHashMap> linkedHashMaps) {
Document doc = getDocument();
Element root = doc.createElement("root");
for (Map<String, Object> element : linkedHashMaps) {
Element e = doc.createElement(element.getKey());
e.setTextContent(element.getValue());
root.appendChild(e);
}
}
}

Related

javax.swing.text.html.HTMLDocument getElement ByName

I am looking for ways to grab an element by name. I tried iterating one element at a time by using Element.getAttributes.getAttributeNames() and iterated through each element to find the name then checked it with the name I am looking for. Any alternatives or optimized way to grab the element directly?
This is the method I use to retrieve elements by tag name. For mixed-content elements (e.g., sub, sup, b, i), you need to look in the attributes of the “fake” content elements.
/**
* Returns all elements of a particular tag name.
*
* #param tagName The tag name of the elements to return (e.g., HTML.Tag.DIV).
* #param document The HTML document to find tags in.
* #return The set of all elements in the HTML document having the specified tag name.
*/
public static Element[] getElementsByTagName(HTML.Tag tagName, HTMLDocument document)
{
List<Element> elements = new ArrayList<Element>();
for (ElementIterator iterator = new ElementIterator(document); iterator.next() != null;)
{
Element currentEl = iterator.current();
AttributeSet attributes = currentEl.getAttributes();
HTML.Tag currentTagName = (HTML.Tag) attributes.getAttribute(StyleConstants.NameAttribute);
if (currentTagName == tagName)
{
elements.add(iterator.current());
} else if (currentTagName == HTML.Tag.CONTENT) {
for (Enumeration<?> e = attributes.getAttributeNames(); e.hasMoreElements();)
{
if (tagName == e.nextElement())
{
elements.add(iterator.current());
break;
}
}
}
}
return elements.toArray(new Element[0]);
}
I am looking for ways to grab an element by name.
Perhaps you could use the getElement() method? It takes as an argument the String value for the id of the element you are searching for.

Getting attribute value from node using dom4j

My XML is structured like the example below. I'm trying to get the attribute values out of XML using dom4j.
<baz>
<foo>
<bar a="1" b="2" c="3" />
<bar a="4" b="5" c="6" />
</foo>
</baz>
Currently the nodes are stored into a List with the following code:
public List<Foo> getFoo() {
String FOO_XPATH = "//baz/foo/*";
List<Foo> fooList = new ArrayList<Foo>();
List<Node> fooNodes = _bazFile.selectNodes(FOO_XPATH);
for (Node n : fooNodes) {
String a = /* get attribute a */
String b = /* get attribute b */
String c = /* get attribute c */
fooNodes.add(new Foo(a, b, c));
}
return fooNodes;
}
There is a similar but different question here on SO but that is returning a node's value for a known attribute key/value pair using the following code:
Node value = elem.selectSingleNode("val[#a='1']/text()");
In my case, the code knows the keys but doesn't know the values - that's what I need to store. (The above snippet from the similar question/answer also returns a node's text value when I need the attribute value.)
You have to cast the Node to Element and then use the attribute or attributeValue methods:
for (Node node : fooNodes) {
Element element = (Element) node;
String a = element.attributeValue("a");
...
}
Basically, getting the attribute value from "any node" doesn't make sense, as some node types (attributes, text nodes) don't have attributes.
You can also use xpath to get the value of a node attribute -
for (Node n : fooNodes) {
String a = n.valueOf("#a");
String b = n.valueOf("#b");
String c = n.valueOf("#c");
fooNodes.add(new Foo(a, b, c));
}
public List<Foo> getFoo() {
String FOO_XPATH = "//baz/foo/*";
List<Foo> fooList = new ArrayList<Foo>();
List<Node> fooNodes = _bazFile.selectNodes(FOO_XPATH);
for (Node n : fooNodes) {
Element element = (Element) n;
String a = element.attributeValue("a");
String b = element.attributeValue("b");
String c = element.attributeValue("c");
fooNodes.add(new Foo(a, b, c));
}
return fooNodes;
}
I think you need to convert node into element then only its works fine.

compare jsoup elements

hello guys i am try to compare one jsoup element with all other elements and if two elements are equal i need to make count++; in this case i need to compare all elements in links1 with all elements in links2 links3 links4....
Document document1 = Jsoup.parse(webPage1);
Elements links1 = document1.select("example");
Document document2 = Jsoup.parse(webPage2);
Elements links2 = document2.select("example");
Document document3 = Jsoup.parse(webPage3);
Elements links3 = document3.select("example");
Document document4 = Jsoup.parse(webPage4);
Elements links4 = document4.select("example");
what would be the code....in JSP....
Elements is just a List of Element, so compating will look like:
for (Element element : links1) {
if(links2.contains(element)){
count++;
}
//maybe do the same thing with links3 links4.
}
If you want do it in JSP — this is another question.

Traversing a deep data structure & deleting object

I have a function to traverse a complex deep HashMap structure. My problem is that when I find the desired node, and do any action on it, such as deleting it, I'm not actually doing any action on the data structure, but instead I'm operating on a copy of the data structure. I'd think a pointer such as in C++ would solve my problem, so how can I do this in Java?
The code:
private HashMap parentNode = null;
// a complex JSON string of arrays / objects, won't list for brevity
private String jsonString = ...
// parses JSON string into HashMaps for objects and Object[ ]s for arrays
private HashMap arr = (HashMap)JSON.parse(jsonString);
// find the node with an id of 27
HashMap parent = findNode(arr, "27");
// Print arr before modifying node
System.out.println(arr);
// modify parent in some way
parent = null;
// Print arr after modifying node
System.out.println(arr);
public HashMap findNode(HashMap map, String id) {
parentNode = null;
findNodeRecursive(map, id);
return parentNode;
}
public void findNodeRecursive(HashMap map, String id) {
for(Object entry : map.entrySet()){
Object value = ((Map.Entry)entry).getValue();
if((value instanceof String) && ((String)value).equals(id))
parentNode = map;
else if(value instanceof HashMap)
findNodeRecursive((HashMap)value,id);
else if(value instanceof Object[])
for(int i=0; i<((Object[])value).length; i++)
findNodeRecursive( (HashMap)(((Object[])value)[i]) ,id);
}
}
To delete the node you want (parent), change your
parent = null;
to
arr.remove(parent);
Setting it to null does not delete anything, simply changes the reference that once was pointing to the node, back to null. To delete, you need to do it explicitly by using the HashMap.remove() method

How to overwrite root element

I have a come to a scenario whereby I need to overwrite the root (w3c dom) Document element with a new element after it has been created elsewhere. So far I have tried two different ways of achieving this:
document.removeChild(document.getDocumentElement());
AND subsequently this:
newElement = document.getDocumentElement();
newElement = document.createElement("newRootElementName");
document.appendChild(newElement);
Neither seem to overwrite the root element, and, after saving, the document seems only to contain the root element that is empty.
Going with the example I found here, here's how you could do it. Since there's apparently no method to change the name of an element, you would have to do the following:
Create another element with the new name
Copy the old element's attributes
Copy the old element's children
And finally replace the node.
For example:
// Obtain the root element
Element element = document.getDocumentElement();
// Create an element with the new name
Element element2 = document.createElement("newRootElementName");
// Copy the attributes to the new element
NamedNodeMap attrs = element.getAttributes();
for (int i=0; i<attrs.getLength(); i++) {
Attr attr2 = (Attr)document.importNode(attrs.item(i), true);
element2.getAttributes().setNamedItem(attr2);
}
// Move all the children
while (element.hasChildNodes()) {
element2.appendChild(element.getFirstChild());
}
// Replace the old node with the new node
element.getParentNode().replaceChild(element2, element);

Categories