XOM getting attribute from Node? - java

Shouldn't something like this work?
Assuming a document formatted as such:
<root>
<element id = "a"></element>
</root>
Node node = doc.query("/root/element").get(0);
String id = node.getDocument().getRootElement().getAttribute("id");
When I print the value of the root element, it looks as if this should work. What's failing, here?

Cast your node to an Element, and you're good to go.

node.getDocument().getRootElement() at this point you have the element which does not have an attribute "id".
Try node.getAttribute("id") instead ? (assuming node is not null)

Related

Xpath Contains Query on child node to return Parent node

String query = null;
XPathExpression expr;
Object Result = null;
expr = xpath.compile("//table/column[contains(translate(text(),'ABCDEFGHIJKLMNAOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz'),'"+query+"')]//text()");
result = expr.evaluate(doc, XpathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i<nodes.getLength(); i++){
System.out.println(nodes.item(i).getParentNode().getNodeName() + "" + nodes.item(i).getNodeValue());
}
Hi, so I want to start off by saying I am new to xpath and fairly new to java. I am trying to create a query interface for this large xml file and this is what I have come up with so far. The xml file is full of logs and it is setup somewhat like this....
<database>
<table>
<column1>
<column2>
<column3>
.....
The code works well at pulling back the column that match the search term however I would like it to pull back the whole table and then print it out. this will give me more valuable info including the date stamp the person who entered it ect.... I have tried various things from trying to get the parentnode from nodes(i) then putting the .getchildnodes into another nodelist but that didn't work at all. I also tried adding /.. at the end of the xpath before the text() to see if it would give me back the parent but that ended up just giving me the root tag somehow. I think I am kinda close, maybe not I don't know but if anyone can help that would be much appreciated, I have been stuck on this for a while now.
I think you want to use .. instead of //
For example to get all table with a td value of xxx you could use
//table/tr/td[text() = 'xxx']/../..

XPath search by "id" attribute , giving NPE - Java

All,
I have multiple XML templates that I need to fill with data, to allow my document builder class to use multiple templates and insert data correctly
I designate the node that I want my class to insert data to by adding an attribute of:
id="root"
One example of an XML
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<SiebelMessage MessageId="07f33fa0-2045-46fd-b88b-5634a3de9a0b" MessageType="Integration Object" IntObjectName="" IntObjectFormat="Siebel Hierarchical" ReturnCode="0" ErrorMessage="">
<listOfReadAudit >
<readAudit id="root">
<recordId mapping="Record ID"></recordId>
<userId mapping="User ID"></userId>
<customerId mapping="Customer ID"></customerId>
<lastUpd mapping="Last Updated"></lastUpd>
<lastUpdBy mapping="Last Updated By"></lastUpdBy>
<busComp mapping="Entity Name"></busComp>
</readAudit>
</listOfReadAudit>
</SiebelMessage>
Code
expr = xpath.compile("//SiebelMessage[#id='root']");
root = (Element) expr.evaluate(xmlDoc, XPathConstants.NODE);
Element temp = (Element) root.cloneNode(true);
Using this example:
XPath to select Element by attribute value
The expression is not working:
//SiebelMessage[#id='root']
Any ideas what I am doing wrong?
Try this:
//readAudit[#id='root']
This selects all readAudit elements with the id attribute set to root (it should be just 1 element in your case).
You could make sure it returns maximum 1 element with this:
//readAudit[#id='root'][1]
What you are doing is selecting SiebelMessage nodes with the attribute id='root'.
But the SiebelMessage doesn't have an id, it's the readAudit you are after. So either do
//readAudit[id='root']
or
//SiebelMessage//readAudit[id='root']

dom4j-java- how to change the value of an attribute

In a Java program, i am processing an xml using dom4j.
Now, I want to update an attribute of an element.
This is the code I am using to obtain that element--
SAXReader reader = new SAXReader();
doc = reader.read(new StringReader(xmlinput));
Element root = doc.getRootElement();
for ( Iterator i = root.elementIterator( "cloudwhile" ); i.hasNext(); ) {
Element foo = (Element) i.next();
Now, I want to update the value of an attribute of element 'foo'--
For this I am trying to use the following code--
foo.setAttributeValue("indexstart", (String) newstart );
However the above method is deprecated... how do I update the attribute now? Also, I want to take the string representation of the modified xml, immediately after updating the attribute of element 'foo'- how do I do that?
JavaDoc says to use addAttribute(...) instead. The name is somewhat misleading, as it will replace the content of an existing attribute - what is equal to updating a value.
Adds the attribute value of the given fully qualified name. If an attribute already exists for the given name it will be replaced. Attributes with null values are silently ignored. If the value of the attribute is null then this method call will remove any attributes with the given name.
As it says in the docs, use addAttribute(String attributeName, String value) instead.

dom4J: How to get the value of Elements of a Node?

I am reading an XML using dom4j by using XPath techniques for selecting desired nodes. Consider that my XML looks like this:
<Employees>
<Emp id=1>
<name>jame</name>
<age>12</age>
</Emp>
.
.
.
</Employees>
Now i need to store the Information of all employees in a list of my Employee Class. Until i code the following:
List<? extends Node> lstprmntEmps = document.selectNodes("//Employees/Emp");
ArrayList<Employee> Employees = new ArrayList<Employee>();//Employee is my custom class
for (Node node : lstprmntEmps)
{
Employees.add(ParseEmployee(node));//ParseEmployee(. . .) is my custom function that pareses emp XML and return Employee object
}
Now how do i get the name and age of Currently selected Node?
is there any such method exist node.getElementValue("name");
Cast each node to Element, then ask the element for its first "name" sub-element and its first "age" sub-element and get their text.
See http://dom4j.sourceforge.net/apidocs/org/dom4j/Element.html.
The elementText(String) method of Element maybe gets a sub-element by name and retrieves its text in one operation, but it's undocumented, so it's hard to say.
Note that variables and methods should always start with a lowercase letter in Java.

Find duplicated XML Element Names (xPath with variable)

I'm using XPATH 1.0 parsers alongside CLiXML in my JAVA project, I'm trying to setup a CLiXML constraint rules file.
I would like to show an error if there are duplicate element names under a specific child.
For example
<parentNode version="1">
<childA version="1">
<ignoredChild/>
</childA>
<childB version="1">
<ignoredChild/>
</childB>
<childC version="4">
<ignoredChild/>
</childC>
<childA version="2">
<ignoredChild/>
</childA>
<childD version="6">
<ignoredChild/>
</childD>
</parentNode>
childA appears more than once, so I would show an error about this.
NOTE: I only want to 'check/count' the Element name, not the attributes inside or the children of the element.
The code inside my .clx rules file that I've tried is:
<forall var="elem1" in=".//parentNode/*">
<equal op1="count(.//parentNode/$elem1)" op2="1"/>
</forall>
But that doesn't work, I get the error:
Caused by: class org.jaxen.saxpath.XPathSyntaxException: count(.//PLC-Mapping/*/$classCount: 23: Expected one of '.', '..', '#', '*', <QName>
As I want the code to check each child name and run another xPath query with the name of the child name - if the count is above 1 then it should give an error.
Any ideas?
Just try to get list of subnodes with appropriate path expression and check for duplicates in that list:
XPathExpression xPathExpression = xPath.compile("//parentNode/*");
NodeList children = (NodeList) xPathExpression.evaluate(config, XPathConstants.NODESET);
for (int i = 0; i < children.getLength(); i++) {
// maintain hashset of clients here and check if element is already there
}
This cannot be done with a single XPath 1.0 expression (see this similar question I answered today).
Here is a single XPath 2.0 expression (in case you can use XPath 2.0):
/*/*[(for $n in name()
return count(/*/*[name()=$n])
)
>1
]
This selects all elements that are children of the top element of the XML document and that occur more than once.

Categories