Unexpected difference found when comparing elements with empty elements in xmlUnit - java

Comparing these two snippets of XML:
testXml:
<ELEMENT1>
<CHILD1></CHILD1>
</ELEMENT1>
actualXml:
<ELEMENT1>
<CHILD1>notEmpty</CHILD1>
</ELEMENT1>
using:
Diff diff = new Diff(testXml, actualXml);
Detailed detailedDiff = new DetailedDiff(diff);
Now detailedDiff.getAllDifferences(); will return a DifferenceConstants.HAS_CHILD_NODES_ID difference and if you print the difference to the console it looks like this:
Expected presence of child nodes to be 'false' but was 'true' - comparing <CHILD1...> at /ELEMENT1[1]/CHILD1[1] to <CHILD1...> at /ELEMENT1[1]/CHILD1[1]
My question is, why is the difference of type DifferenceConstants.HAS_CHILD_NODES_ID and not DifferenceConstants.TEXT_VALUE_ID? The structure of the two XML-snippets are the same, but the text value of the two differs.
So, why doesn't that trigger a difference?

Try to use this ElementQualifier:
Diff diff = new Diff(testXml, actualXml);
diff.overrideElementQualifier(new RecursiveElementNameAndTextQualifier() );
Detailed detailedDiff = new DetailedDiff(diff);
here is the description from javadoc:
public RecursiveElementNameAndTextQualifier()
Uses element names and the text nested an arbitrary level of child
elements deeper into the element to compare elements. Checks all
nodes, not just first child element.
Does not ignore empty text nodes.
The interested thing here is the "does not ignore empty text nodes".
It seems that the default ElementQualifier treats empty nodes as a missing node, and only checks for the first error related to one node. So in your case, possibly solely the "HAS_CHILD_NODES_ID" is thrown instead of including also "TEXT_VALUE_ID".
At least, RecursiveElementNameAndTextQualifier goes deeper.

Related

Remove certain element from array in Velocity Template Language (VTL)

I would like to remove a certain element from an array in Velocity Template Language. I did not find any appropriate method looking through the documentation of Apache VTL, that's why I am asking here for help. I have tried following (.remove() doesn't seem to be a method on array items):
#set($linkedWIARRAY = ["ABC-123, DEF-345, GHI-678"])
#set($dummy=$linkedWIARRAY.add("JKL-901"))
#set($dummy = $linkedWIARRAY.remove("DEF-345"))
$linkedWIARRAY
$linkedWIARRAY returns [ABC-123, DEF-345, GHI-678, JKL-901], showing that remove very likely doesn't exist as method on arrays ;)
There is a similar question on SO, that didn't help me:
velocity template drop element from array
The problem lies in the initialization of the list. It should be:
#set($linkedWIARRAY = ["ABC-123", "DEF-345", "GHI-678"])
that is, each string should be enclosed in double quotes, not the whole string.

How can I set same Value for multiple Keys in Java properties?

I wish to achieve something like -
File.properties contains,
prop1, prop2 = valueX
prop3, prop4 = valueZ
where `props.getProperty("prop1");` should return `valueX`
I know one way is to write the same value again different keys but that makes my property file cluttered and does not provide an analytical view for the business purpose.
PS: If it is somehow possible then, please describe the case where the same key appears with different values.
I wish to achieve something like
File.properties contains,
prop1, prop2 = valueX
prop3, prop4 = valueZ
where props.getProperty("prop1"); should return valueX
The documentation for the .properties file format and the DTD for the XML properties format both provide only for mapping a single key at a time to an associated literal value. These simple formats do not support what you describe. The only alternative they afford is to give a value for each key separately, duplicating values as needed.
that makes my property file cluttered and does not provide an analytical view for the business purpose.
I guess that's in the eye of the beholder. Personally, I think your variation is just the flip side of the same coin. Either way, it is unclear whether keys bearing identical values do so incidentally or because it is important that their values be the same. And as far as writing such files for human consumption, I prefer the keys to be separate, as that makes them easier to find, and better affords grouping and sorting them.
If it is somehow possible then, please describe the case where the same key appears with different values.
Huh? Each key should have exactly one value. It is not documented what should happen if the same key appears more than once.
Perhaps you mean the same value being assigned to different keys, but I don't understand why that's in any question. Nevertheless, here:
prop1 = valueX
prop2 = valueX
prop3 = valueZ
prop4 = valueZ
Note that the = symbols can be replaced with : or just whitespace if you prefer. If you don't like that then you can define your own format, and write your own code for parsing an instance into a Properties object.

HtmlUnit - getByXPath with unknown element type

I'm using HtmlUnit to scrape data and I'm getting used to the syntax of XPath.
However I've run into a problem.
I have an element that I need to pull that varies between pages, sometimes it is a "span" element and sometimes it is an "a" element (a link). The reason being simply sometimes the item I am scraping has a link and sometimes it is just plain text (to state the obvious).
What is the same however is an attribute called "data-reactid", which always has a set value of, let's just say 99.
I've been reading and messing around, and have been trying things like this:
HtmlElement element = (HtmlElement) myPage.getFirstByXPath("//#data-reactid='99'");
System.out.println(element.getTextContent());
I am getting the following error:
java.lang.ClassCastException: java.lang.Boolean cannot be cast to com.gargoylesoftware.htmlunit.html.HtmlElement
Why getFirstByXPath() is returning a boolean is beyond me.
So my question is, how can I access an element by a specified attribute and value, when I do not know what type the element will be?
Thanks!
It's giving you a boolean because your XPath is asking for a boolean. Your XPath,
//#data-reactid='99'
is asking the question "does there exist a data-reactid attribute anywhere in my document with a value of 99?"
What you want is a predicate -- that is, "select elements where this logical condition is true". For all elements (we'll use a * wildcard since we don't know the name) that have a #data-reactid of 99:
//*[#data-reactid = '99']

Find difference between xml file contents

I am comparing my XML files using the sample code (Possible duplicate) in the below post by acdcjunior - Best way to compare 2 XML documents in Java
I see the below error from the assert test.
Expected presence of doctype declaration 'null' but was 'not null' - comparing at to <!DOCTYPE plist PSECTOR " ..........
Can someone please guide me what I can do to fix this?
Okay, I found the solution here - http://xmlunit.sourceforge.net/userguide/XMLUnit-Java.pdf
For efficiency reasons a Diff stops the comparison process as soon as the first difference is found. To get all the differences
between two pieces of XML an instance of the DetailedDiff class, a subclass of Diff, is required. Note that a Detailed
Diff is constructed using an existing Diff instance.
For future readers, here is the solution (also in the link - Pg 9) -
DifferenceListener myDifferenceListener = new IgnoreTextAndAttributeValuesDifferenceListener();
Diff myDiff = new Diff(expectedXML, actualXML);
myDiff.overrideDifferenceListener(myDifferenceListener);
Assert.assertTrue("test XML matches control skeleton XML", myDiff.similar());
From the link again,
The DifferenceEngine class generates the events that are passed to a DifferenceListener implementation as two
pieces of XML are compared. Using recursion it navigates through the nodes in the control XML DOM, and determines which
node in the test XML DOM qualifies for comparison to the current control node. The qualifying test node will match the control
node’s node type, as well as the node name and namespace (if defined for the control node).

XSD: Index of sequence in Element name

I'm building an XSD to generate JAXB objects in Java. Then I ran into this:
<TotalBugs>
<Bug1>...</Bug1>
<Bug2>...</Bug2>
...
<BugN>...</BugN>
</TotalBugs>
How do I build a sequence of elements where the index of the sequence is in the element name? Specifically, how do I get the 1 in Bug1
You don't want to do it in this way, XML has a top-down order by nature. Consequently, you don't have to enumerate yourself:
<totalBugs>
<bug><!-- Here comes 1st bug --></bug>
<bug><!-- Here comes 2nd bug --></bug>
...
<bug><!-- Here comes last bug --></bug>
</totalBugs>
You can access the 1st bug node in the list by the XPath expression:
/totalBugs/bug[1]
Note, indexes start by W3C standard at 1. Please refer to for further readings to w3schools.
I'm pretty sure XSD won't support what you need. However you can use <xsd:any> for that bit of the schema, then use something lower-level than JAXB to generate the XML for that particular part. (I think your generated classes will have fields like protected List<Element> any; which you can fill in using DOM).

Categories

Resources