JDK 1.7.0
XMLUnit 1.3
When comparing this control XML string:
String controlXml = "" +
"<client>" +
" <name>Hello World</name>" +
"</client>";
With this test XML string:
String testXml = "" +
"<client>" +
" <name>Hello World</name>" +
"</client>";
XMLUNIT returns false and I was expecting it to return true (no differences).
Here is my usage:
XMLUnit.setIgnoreComments(true);
XMLUnit.setIgnoreWhitespace(true);
Diff diff = new Diff(controlXml,testXml);
boolean result = diff.similar(); //result is false
I also get the following error in the console window:
[Fatal Error] :1:103: The entity "nbsp" was referenced, but not declared.
I'm not sure what to do here.
I looked into it and I got some info about EntityResolver using Google but it's all very confusing.
I need the entity to be treated as plain text. Logically, as plain text, they are equal.
I tried toggling with the following options:
XMLUnit.setExpandEntityReferences(false); //tried true, false
XMLUnit.setIgnoreDiffBetweenTextAndCDATA(false); //tried true, false
Nothing worked.
Please help, I'm totally lost. Thanks!
It appears that there's a difference between character entities ( ) and numerical entities ( ).
XMLUnit has no problems with numerical entities as opposed to character entities.
I'm thinking that a simple character-entity-to-numerical-entity procedure should be sufficient to resolve my problem.
Related
I am using xmlunit 2.5.0.
Below are my two xml string : One is the controlxml and one is testxml.
String controlXml = "<flowers><flower><f1 name = \"Roses\"/></flower><flower><f1 name = \"Daisy\"/></flower><flower><f1 name = \"Crocus\"/></flower></flowers>";
String testXml = "<flowers><flower><f1 name = \"Daisy\"/></flower><flower><f1 name = \"Roses\"/></flower><flower><f1 name = \"Crocus\"/></flower></flowers>";
Here i am comparing these two string xmls using xmlunit.
My java code is:
org.xmlunit.diff.Diff myDiff = DiffBuilder.compare(controlXml).withTest(testXml)
.checkForSimilar()
.withNodeMatcher(new
DefaultNodeMatcher(ElementSelectors.conditionalBuilder()
.whenElementIsNamed("f1")
.thenUse(ElementSelectors.byName)
.elseUse(ElementSelectors.byNameAndText)
.build()))
.build();
Getting error:
***********************
Expected attribute value 'Roses' but was 'Daisy' - comparing <f1 name="Roses"...> at /flowers[1]/flower[1]/f1[1]/#name to <f1 name="Daisy"...> at /flowers[1]/flower[1]/f1[1]/#name (DIFFERENT)
***********************
***********************
Expected attribute value 'Daisy' but was 'Roses' - comparing <f1 name="Daisy"...> at /flowers[1]/flower[2]/f1[1]/#name to <f1 name="Roses"...> at /flowers[1]/flower[2]/f1[1]/#name (DIFFERENT)
***********************
I want to get no error since Rose is present in the testxml. Why is Rose in controlxml is being compared to Daisy in testxml even though i have rose in the testxml and i have ElementSelectors.byName and whenElementIsNamed("f1").
Which ElementSelector should I use?
Your
.whenElementIsNamed("f1")
.thenUse(ElementSelectors.byName)
means your "f1" elements will be in compared in document order. They all have the same name after all. You obviously feel the value of the name attribute is what identifies the "f1"s to compare. If the "f1" would be siblings then a simple
.thenUse(ElementSelectors.byNameAndAttributes("name"))
should work. byNameAndAttributes takes a varargs list of attributes whose values must match in addition to the element name.
Unfortunately they are not siblings and you must tell XMLUnit which "flower" elements to pick when traversing the tree. When XMLUnit picks up the wrong "flower"s, it is never going to see the "f1" you consider the same.
The full solution for your example is
.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.conditionalBuilder()
.whenElementIsNamed("flower")
.thenUse(ElementSelectors.byXPath("./f1", ElementSelectors.byNameAndAttributes("name")))
.elseUse(ElementSelectors.byNameAndText)
.build()))
I am using text fields for displaying column names . For showing the corresponding name of the column I have tried the following method:
Method 1:
textField.setX(currentXPos);
textField.setY(0);
textField.setWidth(columnWidth);
textField.setPrintWhenDetailOverflows(false);
textField.setHeight(colDtlBandHeight);
textField.setStretchWithOverflow(true);
textField.setStretchType(StretchTypeEnum.RELATIVE_TO_BAND_HEIGHT);
textField.setStyle(normalFont);
textField.setBlankWhenNull(true);
JRDesignExpression expression = new JRDesignExpression();
expression.setValueClass(columnClass);
expression.setText("$F{" + columnName + "}");
But on using the above method it throws an exception saying:
net.sf.jasperreports.engine.JRException: Errors were encountered when compiling report expressions class file:
1. Syntax error on token "ID", delete this token
value = SHIFT ID; //$JR_EXPR_ID=44$
2. Syntax error, insert ";" to complete BlockStatements
value = BILL NO.; //$JR_EXPR_ID=45$
3. Syntax error on token ".", invalid VariableDeclarator
value = BILL NO.; //$JR_EXPR_ID=45$
4. Syntax error on token "DATE", delete this token
value = BILL DATE; //$JR_EXPR_ID=46$
But on using the below lines the column Names are set correctly .
Method 2:
textField.setExpression(new JRDesignExpression("new String(\""+colTitle+"\")"));
My doubts are:
1. For displaying the data the first method mentioned is used . Then how come there are no exceptions in that case ?
2. Why did it throw those exceptions when the same method was used for displaying column names?
3. How did the 2nd method work ?
1.:
I suppose the data is properly enclosed in quotes.
2.:
Judging by the exception explanation (e.g. Syntax error on token "ID", delete this token) the interpreter sees two values, SHIFT and ID. It seems here that quotes are missing, e.g.
"SHIFT ID"
"BILL NO."
3.:
In your first example, you create a JRDesignExpression, set the value class and set the text.
The field isn't enclosed in quotes as seen in your lower example. It should look like this:
expression.setText("\"$F{" + columnName + "}\"");
Also, you didn't assign the expression to your textField:
textField.setExpression(expression)
I am trying to do some experiment with the org.apache.commons.lang.StringEscapeUtils class but I am finding some difficulties.
I have the following situation in my code:
String notNormalized = "c'è";
System.out.println("NOT NORMALIZED: " + notNormalized);
System.out.println("NORMALIZED: " + StringEscapeUtils.escapeJava(notNormalized));
So first I have declared the notNormalized field that (at least in my head) have to represent a not normalized string that contains an apostrophe character represented by the ' and an accented vowel represented by the è (that should be the è character)
Then I try to print it without normalization and I espect that is print the c'è string and the its normalized version and I expect to retrieve the c'è normalized\converted string.
But the problem is that I still obtain the same output, infact this is what I obtain in the console as output:
NOT NORMALIZED: c'è
NORMALIZED: c'è
Why? What am I missing? What is wrong? How can I perform this test and correctly convert a string that contains character as &apos ?
What you're looking to do is unescapeHtml4.
So
System.out.println("NORMALIZED: " + StringEscapeUtils.unescapeHtml4(notNormalized));
which prints
NORMALIZED: c'è
Unfortunately, &apos is not an HTML 4 entity and therefore can't be unescaped with this tool. You can use unescapeXml for the &apos but not for the è. You'll have to mix and match.
I have run into an interesting problem which I'm pretty sure is the fault of HashMap. Consider the following debug code (AMap is a HashMap, key is a value passed to this method)
System.out.println("getBValues - Given: " + key);
System.out.println("getBValues - Contains Key: " + AMap.containsKey(key));
System.out.println("getBValues - Value: " + AMap.get(key));
for(Map.Entry<A,HashSet<B>> entry : AMap.entrySet()) {
System.out.println("getBValues(key) - Equal: " + (key.equals(entry.getKey())));
System.out.println("getBValues(key) - HashCode Equal: "+(key.hashCode() == entry.getKey().hashCode()));
System.out.println("getBValues(key) - Key: " + entry.getKey());
System.out.println("getBValues(key) - Value: " + entry.getValue());
}
Now in this Map I insert a single key (Channel) and value. Later I try and get the value back with get() and run this debug code which in my case gives this output:
getBValues - Given: Channel(...)
getBValues - Contains Key: false <--- Doesnt contain key?!
getBValues - Value: null <--- Null (bad)
getBValues(key) - Equal: true <--- Given key and AMap key is equal
getBValues(key) - HashCode Equal: true
getBValues(key) - Key: Channel(Same...)
getBValues(key) - Value: [] <--- Not null (This is the expected result)
As you can see, fetching the key from the HashMap directly doesn't work but looping through I get the exact same key, meaning its there it just can't be found with get(). My question is what would cause this? How can get() not find a key that exists?
I would provide an some example code of this but I can't seem to reproduce this independently.
Any suggestions on what might be causing this?
I'll bet you didn't override equals and hashCode properly in your key Channel class. That would explain it.
Joshua Bloch tells you how to do it correctly in his "Effective Java" Chapter 3.
http://java.sun.com/developer/Books/effectivejava/Chapter3.pdf
From what I can see, we still haven't ruled out if it has to do with immutability.
If you do:
aMap.put(key, value);
key.setFieldIncludedInHashCodeAndEquals(25);
then you would get the result from above.
To rule this out, either show us more of your code or, in the for loop in your example above, add
System.out.println(aMap.get(entry.getKey()));
Also, use a debugger. That way, you can see if your object is in the correct bucket.
I see an example of doing a partial string search on the GAE google group (this thread):
String term1 = "cow";
String term2 = "horse";
Query q;
q.setFilter("name.matches('" + term1 + "%')");
so this works like:
"Find all objects of the class where property 'name' starts with term1"
so that would match stuff like:
cowfoo
cowgrok
cowetc
right? I could then replace term1 with term2, and find all instances that begin with 'horse'. Is there a doc that explains this anymore? I just want to check this is how it really works before I make a decision on how to store some strings for my data model,
Thanks
I can't find the docs which present the prefix matching syntax you presented, but your logic is sound. And it looks like the syntax is supported based on the google group message you cited.
For the Python runtime, I would perform a prefix match by using an inequality filter. You can also do this on the Java runtime like this (and this is probably how the % syntax is implemented):
// prefix is some string object
q.setFilter("my_string_field >= :1 && my_string_field < :2");
q.execute(prefix, (prefix + "\ufffd"));