DisplayTool installation and usage - maven

I am using Velocity 1.7 to format string and I had some trouble with default values. Velocity by itself has no special syntax for case when value is not set and we want to use some another, default value.
By the means of Velocity it looks like:
#if(!${name})Default John#else${name}#end
which is unconveniant for my case.
After googling I've found DisplayTool, according to documentation it will look like:
$display.alt($name,"Default John")
So I added maven dependency but not sure how to add DisplayTool to my method and it is hard to found instructions for this.
Maybe somebody can help with advice or give useful links?..
My method:
public String testVelocity(String url) throws Exception{
Velocity.init();
VelocityContext context = getVelocityContext();//gets simple VelocityContext object
Writer out = new StringWriter();
Velocity.evaluate(context, out, "testing", url);
logger.info("got first results "+out);
return out.toString();
}
When I send
String url = "http://www.test.com?withDefault=$display.alt(\"not null\",\"exampleDefaults\")&truncate=$display.truncate(\"This is a long string.\", 10)";
String result = testVelocity(url);
I get "http://www.test.com?withDefault=$display.alt(\"not null\",\"exampleDefaults\")&truncate=$display.truncate(\"This is a long string.\", 10)" without changes, but should get
"http://www.test.com?withDefault=not null&truncate=This is...
Please tell me what I am missing. Thanks.

The construction of the URL occurs in your Java code, before you invoke Velocity, so Velocity isn't going to evaluate $display.alt(\"not null\",\"exampleDefaults\"). That syntax will be valid only in a Velocity template (which typically have .vm extensions).
In the Java code, there's no need to use the $ notation, you can just call the DisplayTool methods directly. I've not worked with DisplayTool before, but it's probably something like this:
DisplayTool display = new DisplayTool();
String withDefault = display.alt("not null","exampleDefaults");
String truncate = display.truncate("This is a long string.", 10);
String url = "http://www.test.com?"
+ withDefault=" + withDefault
+ "&truncate=" + truncate;
It might be better, though, to call your DisplayTool methods directly from the Velocity template. That's what is shown in the example usage.

Related

Removing Class Name of an element using element.className.replace method

var divfoo=document.getElementById("foo");
divfoo.className=" css-class css-class2 ";
divfoo.className=divfoo.className.replace(" css-class2 ", "");
The above code works. but I would like to make changes to last line of above code which is using replace method. Instead of writing the code like above, I would like to know why doesn't it work when written like below.
var divfoo=document.getElementById("foo");
divfoo.className=" css-class css-class2 ";
divfoo.className.replace(" css-class2 ", "");
Why should one assign to "divfoo.className" when applying replace method to the same "divfoo.className", why can't we just apply method directly like above code did?
Because of this should I hate javascript for not being logical?
enter code here
Element.className is a plain string representation of class HTML attribute.
String.replace method does not change the source string that is called on, just returns the result of replacement procedure.
If you want more "logical / functional" approach, look at Element.classList interface, namely the remove method.

Disallow DTD's while evaluating xpath

I have below code to evaluate xpath expression.
String inputXml = "<?xml version=\"1.0\"?><!DOCTYPE document SYSTEM \"test.dtd\"><Request><Header><Version>1.0</Version></Header></Request>";
String xpath="/Request/Header/Version";
XPathFactory xpf = new net.sf.saxon.xpath.XPathFactoryImpl();
final InputSource is = new InputSource(new StringReader(inputXml));
String version = xpf.newXPath().evaluate(xpath, is);
xpf.newXPath().evaluate throws error as test.dtd couldn't be found. I want to disallow DTD completely. I have been reading about setting SAXParser feature "http://apache.org/xml/features/disallow-doctype-decl" but not sure how to apply in this case or is there any other way to disallow/ignore DTD's.
I'm not quite sure what you want to achieve. If you want this to fail because there is a DTD referenced, then you already seem to be achieving that.
However, if you want to set a property on the XML parser, there are two ways you could achieve it:
(a) Supply a SAXSource rather than an InputSource; initialize the XMLReader in the SAXSource to the XML parser you want to use, and use the XMLReader's setFeature interface to configure it before you pass it to the XPath engine.
(b) Set the Saxon configuration feature http://saxon.sf.net/feature/parserFeature?uri=http://apache.org/xml/features/disallow-doctype-decl (that's a single string with no spaces or newlines) to the value true. You can do this using
xpf.getConfiguration().setConfigurationProperty(featureName, true);

TextBox1.Text string on end of a link

I wanted to make an application that checks if a link was blocked on steam.
I used the linkfilter page. (https://steamcommunity.com/linkfilter/?url=)
I tried doing it like this:
WebBrowser1.Url = https://steamcommunity.com/linkfilter/?url=(TextBox1.Text)
But I got two errors. Is there a way to do this?
Did you try setting your string values as actual strings?:
WebBrowser1.Url = new Uri("https://steamcommunity.com/linkfilter/?url=" + TextBox1.Text);
or:
WebBrowser1.Url = new Uri(string.Format("https://steamcommunity.com/linkfilter/?url={0}", TextBox1.Text));

How to return localized content from WebAPI? Strings work but not numbers

Given this ApiController:
public string TestString() {
return "The value is: " + 1.23;
}
public double TestDouble() {
return 1.23;
}
With the browser's language set to "fr-FR", the following happens:
/apiController/TestString yields
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">The value is: 1,23</string>
/apiController/TestDouble yields
<double xmlns="http://schemas.microsoft.com/2003/10/Serialization/">1.23</double>
I would expect TestDouble() to yield 1,23 in the XML. Can anyone explain why this isn't the case and, more importantly, how to make it so that it does?
It is because the conversion from double to string happens at different stage for each API. For the TestString API, double.ToString() is used to convert the number to a string using CurrentCulture of the current thread and it happens when the TestString method is called. Meanwhile, the double number which is returned by TestDouble is serialized to string during the serialization step which uses GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.Culture.
In my opinion, both should use InvariantCulture. On the consumer side, the values will be parsed and be formatted with the correct culture.
Update: this is only used for JsonFormatter. XmlFormatter doesn't have such a setting.
Update 2:
It seems (decimal) numbers need special converter to make it culture-aware:
Handling decimal values in Newtonsoft.Json
Btw, if you want o change data format per action/request, you can try the last piece of code of the following link: http://tostring.it/2012/07/18/customize-json-result-in-web-api/

Image tag not closing with HTMLAgilityPack

Using the HTMLAgilityPack to write out a new image node, it seems to remove the closing tag of an image, e.g. should be but when you check outer html, has .
string strIMG = "<img src='" + imgPath + "' height='" + pubImg.Height + "px' width='" + pubImg.Width + "px' />";
HtmlNode newNode = HtmlNode.Create(strIMG);
This breaks xhtml.
Telling it to output XML as Micky suggests works, but if you have other reasons not to want XML, try this:
doc.OptionWriteEmptyNodes = true;
Edit 1:Here is how to fix an HTML Agilty Pack document to correctly display image (img) tags:
if (HtmlNode.ElementsFlags.ContainsKey("img"))
{ HtmlNode.ElementsFlags["img"] = HtmlElementFlag.Closed;}
else
{ HtmlNode.ElementsFlags.Add("img", HtmlElementFlag.Closed);}
replace "img" for any other tag to fix them as well (input, select, and option come up frequently). Repeat as needed. Keep in mind that this will produce rather than , because of the HAP bug preventing the "closed" and "empty" flags from being set simultaneously.
Source: Mike Bridge
Original answer:
Having just labored over solutions to this issue, and not finding any sufficient answers (doctype set properly, using Output as XML, Check Syntax, AutoCloseOnEnd, and Write Empty Node options), I was able to solve this with a dirty hack.
This will certainly not solve the issue outright for everyone, but for anyone returning their generated html/xml as a string (EG via a web service), the simple solution is to use fake tags that the agility pack doesn't know to break.
Once you have finished doing everything you need to do on your document, call the following method once for each tag giving you a headache (notable examples being option, input, and img). Immediately after, render your final string and do a simple replace for each tag prefixed with some string (in this case "Fix_", and return your string.
This is only marginally better in my opinion than the regex solution proposed in another question I cannot locate at the moment (something along the lines of )
private void fixHAPUnclosedTags(ref HtmlDocument doc, string tagName, bool hasInnerText = false)
{
HtmlNode tagReplacement = null;
foreach(var tag in doc.DocumentNode.SelectNodes("//"+tagName))
{
tagReplacement = HtmlTextNode.CreateNode("<fix_"+tagName+"></fix_"+tagName+">");
foreach(var attr in tag.Attributes)
{
tagReplacement.SetAttributeValue(attr.Name, attr.Value);
}
if(hasInnerText)//for option tags and other non-empty nodes, the next (text) node will be its inner HTML
{
tagReplacement.InnerHtml = tag.InnerHtml + tag.NextSibling.InnerHtml;
tag.NextSibling.Remove();
}
tag.ParentNode.ReplaceChild(tagReplacement, tag);
}
}
As a note, if I were a betting man I would guess that MikeBridge's answer above inadvertently identifies the source of this bug in the pack - something is causing the closed and empty flags to be mutually exclusive
Additionally, after a bit more digging, I don't appear to be the only one who has taken this approach:
HtmlAgilityPack Drops Option End Tags
Furthermore, in cases where you ONLY need non-empty elements, there is a very simple fix listed in that same question, as well as the HAP codeplex discussion here: This essentially sets the empty flag option listed in Mike Bridge's answer above permanently everywhere.
There is an option to turn on XML output that makes this issue go away.
var htmlDoc = new HtmlDocument();
htmlDoc.OptionOutputAsXml = true;
htmlDoc.LoadHtml(rawHtml);
This seems to be a bug with HtmlAgilityPack. There are many ways to reproduce this, for example:
Debug.WriteLine(HtmlNode.CreateNode("<img id=\"bla\"></img>").OuterHtml);
Outputs malformed HTML. Using the suggested fixes in the other answers does nothing.
HtmlDocument doc = new HtmlDocument();
doc.OptionOutputAsXml = true;
HtmlNode node = doc.CreateElement("x");
node.InnerHtml = "<img id=\"bla\"></img>";
doc.DocumentNode.AppendChild(node);
Debug.WriteLine(doc.DocumentNode.OuterHtml);
Produces malformed XML / XHTML like <x><img id="bla"></x>
I have created a issue in CodePlex for this.

Resources