For my Java program im using XMLUnit 1.5, wich compares two XML-Files (with Namespaces). But the XPathes, I get, do not contain any Namespaces. How I can tell XMLUnit todo that? Is that possible?
Here is my code:
control = new FileReader(file1);
test = new FileReader(file2);
list = new ArrayList<Unterschied>();
Diff diff;
diff = new Diff(control, test);
diff.overrideElementQualifier(new ElementNameAndAttributeQualifier());
if (diff.similar())
{
MessageDialog.openInformation(null, "Info", "Similar");
}
else if (!diff.similar())
{
DetailedDiff detDiff = new DetailedDiff(diff);
detDiff.overrieElementQualifier(new ElementNameAndAttributeQualifier());
#SuppressWarnings("unchecked")
List<Object> differences = detDiff.getAllDifferences();
for (Object object : differences)
{
Difference difference = (Difference) object;
if (!difference.isRecoverable() && !difference.getDescription().contains("number of child nodes"))
{
controlXPath = difference.getControlNodeDetail().getXpathLocation(); // without Namespaces!
controlValue = difference.getControlNodeDetail().getValue();
testXPath = difference.getTestNodeDetail().getXpathLocation(); // without Namespaces!
testValue = difference.getTestNodeDetail().getValue();
list.add(new Unterschied(controlOrt, controlWert, testOrt, testWert));
}
}
Later in my program I evaluating these XPathes for getting the correct position of this node. With these position I select the appropriate text in the editor, so that the user can see the Difference.
My code for evaluating:
public void evaluateXPath(String xp, Node node) {
XPath newXPath = new XPathFactoryImpl().newXPath();
XPathExpression xpExp = newXPath.compile(xpath);
NodeList nodeList = (NodeList) xpExp.evaluate(node, XPathConstants.NODESET);
int length = nodeList.getLength();
for (int i=0; i < length; i++) {
IDOMNode iDOMnode = (IDOMNode) nodeList.item(i);
textEditor.selectAndReveal(iDOMnode.getStartOffset(), iDOMnode.getEndOffset()-iDOMnode.getStartOffset());
}
}
Thanks for your help and sorry for my bad english! ;)
No, XMLUnit 1.x will only return plain XPath without any namespace indication at all.
XMLUnit 2.x (under development) will return XPaths using prefixes for namespaces that can be configured per NS-URI.
Related
I am new with Java programming and I have problem reading XML-file. I am trying to save information from XML using DOM parser. I load the xml into a Document and then trying to save all the schedules of a radio channel in a NodeList. but the program saves repeatedly just infromation of the first node. Where is the problem with my code ?
NodeList episodeElement = doc.getElementsByTagName("schedule");
for (int i = 0; i < episodeElement.getLength(); i++) {
Node n = episodeElement.item(i);
if (n.getNodeType() == Node.ELEMENT_NODE && getSize(doc) != 0) {
Element e = (Element) n;
String title = e.getElementsByTagName("title").item(i).getTextContent();
NodeList nd = e.getElementsByTagName("description");
String description;
if (nd.getLength() > 0) {
description = nd.item(i).getTextContent();
}else {
description = null;
}
String startTime = e.getElementsByTagName("starttimeutc").item(i).getTextContent();
String endTime = e.getElementsByTagName("endtimeutc").item(i).getTextContent();
Program prog = new Program(id, title, description, startTime, endTime);
System.out.println(startTime);
programs.add(i, prog);
}
else {
System.out.println("No schedules found");
}
}
You haven't used .getChildNodes() method to traverse a layer down the tag and looped around that, that's why it is just fetching you information of the first node.
Visit this link and u can find an excellent example.
https://www.youtube.com/watch?v=HfGWVy-eMRc
I have to develop an android application.
Here i have follows following xml format.
<Product>
<product name="viki" productid="111">
<ProductType>
<producttype>Nokia</producttype>
<producttype>Samsung</producttype>
</ProductType>
</product>
</Product>
Here i have to get the producttype for particluar product.so i have wrote the following code:
if(subCategoryChildNode.hasChildNodes()){
// parse 'Subcategory' childs
NodeList productNL = subCategoryChildElmt.getElementsByTagName("product");
if(productNL.getLength() > 0){
ArrayList<Product> productAL = new ArrayList<Product>();
Product productBean = null;
for(int pCnt=0;pCnt<productNL.getLength();pCnt++){
Node productNode = productNL.item(pCnt);
Element productElmt = null;
// parse 'product' tag attributes
if(productNode.hasAttributes()){
productBean = new Product();
productElmt = (Element)productNode;
productBean.setmProductName(productElmt.getAttribute("name"));
}
if(productNode.hasChildNodes()){
NodeList productTypeNL = productElmt.getElementsByTagName("ProductType");
if(productTypeNL.getLength() > 0){
ArrayList<ProductType> ProductTypeAL = new ArrayList<ProductType>();
ProductType productTypeBean = null;
for(int ptCnt=0;ptCnt<productTypeNL.getLength();ptCnt++){
Node productTypeNode = productTypeNL.item(ptCnt);
Element productTypeElmt = null;
if(productTypeNode.hasChildNodes()){
productTypeBean = new ProductType();
productTypeElmt = (Element)productTypeNode;
productTypeBean.setmProductType(XMLfunctions.getValue(productTypeElmt,"producttype"));
System.out.println("Product Types are "+ " "+XMLfunctions.getValue(productTypeElmt,"producttype"));
ProductTypeAL.add(productTypeBean);
}
productBean.setmProductTypes(ProductTypeAL);
}
productAL.add(productBean);
}
}
subCategoryBean.setmProducts(productAL);
}
}
subCategoryAL.add(subCategoryBean);
}
Here am getting the value is nokia alone.but i need to display the value nokia,samsung...if i have to run the app means getting single value.but i need to get the list of all values..
What's wrong in my code .. please check and give me solution fot these ???
The reason you're getting only one <producttype> (Nokia) instead of the complete list because you're looping over the length of <ProductType> nodes thinking you're looping over the <producttype> ones.
So, you need another inner loop to cover all the child product type nodes like
for(int ptCnt=0; ptCnt < productTypeNL.getLength(); ptCnt++) {
Node productTypeNode = productTypeNL.item(ptCnt);
if(productTypeNode.hasChildNodes()){
NodeList childProductTypeNL = productTypeNode.getChildNodes();
System.out.print("Product Types are: ");
for (int cptCnt=0; cptCnt < childProductTypeNL.getLength(); cptCnt++) {
productTypeBean = new ProductType();
productTypeBean.setmProductType (
childProductTypeNL.item(cptCnt).getTextContent());
System.out.print(productTypeBean.getmProductType() + ", ");
ProductTypeAL.add(productTypeBean);
}
}
productBean.setmProductTypes(ProductTypeAL);
}
I've directly used the Node.getChildNodes() and Node.getTextContexnt() methods, instead of type casting to Element first and using its methods or the XMLfunctions utility class.
I also recommend using different names for child nodes instead of relying on using a different case to avoid such problems in future. A simple way to avoid name collision (when you're not able to come up with a different name) is to simply use a plural like <ProductTypes> for the parent tag.
However, a better approach when you need to parse deep within a DOM tree is to use an XPath to directly get the list of nodes you're interested in. I'm not entirely sure what the program does but just to give you an example an XPath like
String xpath = "//product[#name=\"viki\"]/ProductType/producttype";
would give you the NodeList for <producttype> nodes directly.
I'd say one of the problem of your code (might be others), is that you declare your productTypeBean and productTypeElmt before your for loop, and since it's not required after, it isn't needed.
if(subCategoryChildNode.hasChildNodes()){
// parse 'Subcategory' childs
NodeList productNL = subCategoryChildElmt.getElementsByTagName("product");
if(productNL.getLength() > 0){
ArrayList<Product> productAL = new ArrayList<Product>();
Product productBean = null;
for(int pCnt=0;pCnt<productNL.getLength();pCnt++){
Node productNode = productNL.item(pCnt);
Element productElmt = null;
// parse 'product' tag attributes
if(productNode.hasAttributes()){
productBean = new Product();
productElmt = (Element)productNode;
productBean.setmProductName(productElmt.getAttribute("name"));
}
if(productNode.hasChildNodes()){
NodeList productTypeNL = productElmt.getElementsByTagName("ProductType");
if(productTypeNL.getLength() > 0){
ArrayList<ProductType> ProductTypeAL = new ArrayList<ProductType>();
for(int ptCnt=0;ptCnt<productTypeNL.getLength();ptCnt++){
Node productTypeNode = productTypeNL.item(ptCnt);
if(productTypeNode.hasChildNodes()){
ProductType productTypeBean = new ProductType();
Element productTypeElmt = (Element)productTypeNode;
productTypeBean.setmProductType(XMLfunctions.getValue(productTypeElmt,"producttype"));
System.out.println("Product Types are "+ " "+XMLfunctions.getValue(productTypeElmt,"producttype"));
ProductTypeAL.add(productTypeBean);
}
productBean.setmProductTypes(ProductTypeAL);
}
productAL.add(productBean);
}
}
subCategoryBean.setmProducts(productAL);
}
}
subCategoryAL.add(subCategoryBean);
}
I want to read a multi level tags from xml(DOM) using java and the sample xml is : <root>
<subclass>
<subclass>
<subclass>
<name>test1</name>
<address>address1</address>
</subclass>
<name>test2</name>
<address>address2</address>
</subclass>
<name>test3</name>
<address>address3</address>
</subclass>
</root>
How to read <name>test2</name> and <address>address2</address> from the above xml?
I have given a sample code .. but i need to find the values dynamically.
when i am iterating bu using subclass tag, it's giving all the data. just i want to know how to get the specific data like <name>test2</name> and <address>address2</address> .
Below is my java code which is reading the above xml:
NodeList fList = firstWordElement
.getElementsByTagName("root");
for (int i = 0; i < fList.getLength(); i++) {
Node firstFLNode = fList.item(i);
if (firstFLNode.getNodeType() == Node.ELEMENT_NODE) {
Element firstWdElement = (Element) firstFLNode;
NodeList firstWdList = firstWdElement.getElementsByTagName("innerclass");
for (int j = 0; j < firstWdList.getLength(); j++) {
Element firstWd1Element = (Element) firstWdList.item(j);
if (firstWd1Element.getNodeType() == Node.ELEMENT_NODE) {
String InnerName = ParseUtil.getTagValue("name", firstWd1Element);
String InnerFormat = ParseUtil.getTagValue("format", firstWd1Element);
String InnerDescription = ParseUtil.getTagValue("description", firstWd1Element);
NodeList innerClassList = firstWd1Element.getElementsByTagName("subclass");
for (int k = 0; k < innerClassList.getLength(); k++) {
Element subClassElement = (Element) innerClassList
.item(k);
if (subClassElement.getNodeType() == Node.ELEMENT_NODE) {
String InnerSubName = ParseUtil.getTagValue("name", subClassElement);
System.out.println("Innername==="+ InnerSubName);
String InnerSubFormat = ParseUtil.getTagValue("format", subClassElement);
System.out.println("Innerformat==="+ InnerSubFormat);
String InnerSubDescription = ParseUtil.getTagValue("description", subClassElement);
System.out.println("Innerdescription==="+ InnerSubDescription);
}
}
}
}
}
}
A quick way to do this is by using XPath queries. Check out these tutorials:
http://www.ibm.com/developerworks/library/x-javaxpathapi/index.html
http://www.javabeat.net/2009/03/how-to-query-xml-using-xpath/
Traditionally you have to iterate trough the nodes, usually done by creating a NodeList with getChildren() from the parent node. If you only want the test2 -node you have to perform some sort of comparison - you can't jump straight to the second node. That is to say you can, but that wont make a very robust or scale able solution.
I am using DOM to parse an XML string as in the following example. This works great except in one instance. The document which I am trying to parse looks like this:
<response requestID=\"1234\">
<expectedValue>Alarm</expectedValue>
<recommendations>For steps on how to resolve visit Website and use the search features for \"Alarm\"<recommendations>
<setting>Active</setting>
<response>
The code I used to parse the XML is as follows:
try {
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xmlResult));
Document doc = db.parse(is);
NodeList nlResponse = doc.getElementsByTagName("response");
String[] String = new String[3]; //result entries
for (int i = 0; i < nlResponse.getLength(); i++) {
Element e = (Element) nlResponse.item(i);
int c1 = 0; //count for string array
NodeList ev = e.getElementsByTagName("expectedValue");
Element line = (Element) ev.item(0);
String[c1] = (getCharacterDataFromElement(line));
c1++;
NodeList rec = e.getElementsByTagName("recommendations");
line = (Element) rec.item(0);
String[c1] = (getCharacterDataFromElement(line));
c1++;
NodeList set = e.getElementsByTagName("settings");
line = (Element) set.item(0);
String[c1] = (getCharacterDataFromElement(line));
c1++;
I am able to parse the code and put the result into a string array (as opposed to the System.out.println()). With the current code, my string array looks as follows:
String[0] = "Alarm"
String[1] = "For steps on how to resolve visit"
String[2] = "Active"
I would like some way of being able to read the rest of the information within "Recommendations" in order to ultimately display the hyperlink (along with other output) in a TextView. How can I do this?
I apologize for my previous answer in assuming your xml was ill-formed.
I think what is happening is that your call to the getCharacterDataFromElement is only looking at the first child node for text, when it will need to look at all the child nodes and getting the href attribute as well as the text for the 2nd child node when looking at the recommendations node.
e.g. after getting the Element for recommendation
String srec = "";
NodeList nl = line.getChildNodes();
srec += nl.item(0).getTextContent();
Node n = nl.item(1);
NamedNodeMap nm = n.getAttributes();
srec += "" + n.getTextContent() + "";
srec += nl.item(2).getTextContent();
String[c1] = srec;
I tried
HTMLElement[] focused = response.getElementsWithAttribute("class", "focused");
I was hoping it would find
<span class="focused">Submit</span>
among others, but all I get back is an empty array.
Google has been no help to me.
So. If you were me and you wanted to get an array of HTMLElements by class name, what would you use?
Edit:
The source
public class ExampleIT extends TestCase {
private final String BASE = "http://localhost:8080/preview.htm?";
#Test
public void testFocusedArePresent() throws MalformedURLException, SAXException, IOException {
WebConversation conversation = new WebConversation();
WebResponse response = conversation.getResponse(BASE + "template=Sample");
HTMLElement[] focused = response.getElementsWithAttribute("class", "focused");
assertTrue(focused.length > 0);
}
}
I hope that helps.
getElementsWithAttribute works for me. Alternatively, you can try iterating over the DOM, looking for an element with a specified class attribute. Here is some sample code:
Document doc = response.getDOM();
List<Node> result = new ArrayList<Node>();
NodeList list = doc.getElementsByTagName("*");
for(int i = 0 ; i < list.getLength() ; i++){
Node n = list.item(i).getAttributes().getNamedItem("class");
if(n!=null && "focused".equals(n.getNodeValue())){
result.add(n);
}
}