I have an issue when converting a string from stringbuilder to string.
The issue is similar to this issue but slightly different:
This is my code simplified:
StringBuilder sb = new StringBuilder();
sb.Append("\"");
sb.Append("Hello World");
sb.Append("\"");
string test = sb.ToString();
Now in the debugger the sb value is:
"Hello World"
In the debugger the test string value is changed to:
\"Hello World\"
When returning the test string value back to the browser the velue is STILL escaped:
\"Hello World\"
I have tried using the string replace:
test = test.Replace("\"", "");
no luck, I tried appending the ASCII character instead of \" and I have also tried a different append
sb.Append('"');
All these with no luck. Can somebody maybe point me in the right direction of why I'm still getting the escape character and how to get rid of it.
Thanks and appreciate any input.
Ok it seems that in WCF the stringBuilder automatically adds escape quotes. This means you can not get away from that. Also I was going about this all wrong. I was trying to return a string where I was supposed to return a serialised JSON object.
I'm not seeing the behavior you describe. Escaping double quotes with the backslash should work. The following snippet of code
var sb = new StringBuilder();
sb.Append("Ed says, ");
sb.Append("\"");
sb.Append("Hello");
sb.Append("\"");
Console.WriteLine(sb.ToString());
foreach (char c in sb.ToString()) Console.Write(c + "-");
Console.ReadKey();
produces
Ed says, "Hello"
E-d- -s-a-y-s-,- -"-H-e-l-l-o-"-
If you are getting actual backslash characters in your final display of the string, that may be getting added by something after the StringBuilder and ToString code.
You can use a verbatim string literal "#" before the string, then enter the quotes twice. This removes the use to use escapes in the string sequence :)
StringBuilder sb = new StringBuilder();
sb.Append(#"""");
sb.Append("Hello World");
sb.Append(#"""");
string test = sb.ToString();
This question and answer thread kept on coming up when searching for the solution.
The confusion, for me, was that the Debugger escaping looks exactly the same as the JSON serializer behaviour that was being applied later when I returned the string to a client. So the code at the top of the thread (and my code) worked correctly.
Once I realised that, I converted the piece of code I was working on return an array (string[] in this case) and store that rather than the original string object. Later the JSONResult serializer then dealt with converting the array correctly.
Related
I am using Java Properties to read a properties file. Everything is working fine, but Properties silently drops the backslashes.
(i.e.)
original: c:\sdjf\slkdfj.jpg
after: c:sdjfslkdfj.jpg
How do I make Properties not do this?
I am using the code prop.getProperty(key)
I am getting the properties from a file, and I want to avoid adding double backslashes
It is Properties.load() that's causing the problem that you are seeing as backslash is used for a special purpose.
The logical line holding all the data
for a key-element pair may be spread
out across several adjacent natural
lines by escaping the line terminator
sequence with a backslash character,
\.
If you are unable to use CoolBeans's suggestion then what you can do is read the property file beforehand to a string and replace backslash with double-backslash and then feed it to Properties.load()
String propertyFileContents = readPropertyFileContents();
Properties properties = new Properties();
properties.load(new StringReader(propertyFileContents.replace("\\", "\\\\")));
Use double backslashes c:\\sdjf\\slkdfj.jpg
Properties props = new Properties();
props.setProperty("test", "C:\\dev\\sdk\\test.dat");
System.out.println(props.getProperty("test")); // prints C:\dev\sdk\test.dat
UPDATE CREDIT to #ewh below. Apparently, Windows recognises front slashes. So, I guess you can have your users write it with front slashes instead and if you need backslashes afterwards you can do a replace. I tested this snippet below and it works fine.
Properties props = new Properties();
props.setProperty("test", "C:/dev/sdk/test.dat");
System.out.println(props.getProperty("test")); // prints C:/dev/sdk/test.dat
Use forward slashes. There is never a need in Java to use a backslash in a filename.
In case you really need a backslash in a properties file that will be loaded (like for a property that is not a file path) put \u005c for each backslash character.
The backslash is treated specially in properties files as indicated in the document provided by #unhillbilly.
#EJP: Backslash is definitely needed if, for example, you wanted to store an NTLM login id in a properties file, where the format is DOMAIN\USERNAME with a backslash. This type of property is not a filename so forward slashes will not work.
Edit: #Max Nanasy: From the document (java.util.Properties load javadoc) mentioned above (emphasis mine)
The method does not treat a backslash character, '\', before a non-valid escape character as an error; the backslash is silently dropped. For example, in a Java string the sequence "\z" would cause a compile time error. In contrast, this method silently drops the backslash. Therefore, this method treats the two character sequence "\b" as equivalent to the single character 'b'
For me, I always had trouble with backslashes in the properties file (even with double backslash '\\') unless I specified the unicode.
Replace \ with \\ as below:
c:\sdjf\slkdfj.jpg
to
c:\\sdjf\\slkdfj.jpg
In addition to Bala R's answer I have the following solution to even keep the newline-semantic of backslashes at the end of a line.
Here is my code:
private static Reader preparePropertyFile(File file) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(file));
StringBuilder result = new StringBuilder();
String line;
boolean endingBackslash = false;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (endingBackslash) {
// if the line is empty, is a comment or holds a new property
// definition the backslash found at the end of the previous
// line is not for a multiline property value.
if (line.isEmpty()
|| line.startsWith("#")
|| line.matches("^\\w+(\\.\\w+)*=")) {
result.append("\\\\");
}
}
// if a backslash is found at the end of the line remove it
// and decide what to do depending on the next line.
if (line.endsWith("\\")) {
endingBackslash = true;
line = line.substring(0, line.length() - 1);
} else {
endingBackslash = false;
}
result.append(line.replace("\\", "\\\\"));
}
if (endingBackslash) {
result.append("\\\\");
}
return new StringReader(result.toString());
}
private static Properties getProperties(File file) throws IOException {
Properties result = new Properties();
result.load(preparePropertyFile(file));
return result;
}
The following code will help :
BufferedReader metadataReader = new BufferedReader(new InputStreamReader(new FileInputStream("migrateSchemaGenProps.properties")));
Properties props = new Properties();
props.load(new StringReader(IOUtils.getStringFromReader(metadataReader).replace("\\", "/")));
It is not realy a good thing to use backslashes in a property-file, as they are the escape character.
Nevertheless: a Windows user will trend to use them in any path... Therefore, in a single line thanks apache common IO:
params.load(new StringReader(IOUtils.toString(paramFile.toURI(), null).replaceAll("\\\\", "/")));
you triple use the backslash to get one:
for example:
key=value1\\value2
in the properties file will turn to
key=value1\value2
in the java Properties object
I am trying to use file name path (Ex: C:\Document\Report.txt) as a parameter through uipath orchastrator api. I tried different approach and In each approach I am getting Bad request error "{"message":"Argument Values validation failed.","errorCode":2003,"resourceIds":null}"
Below is my Example code
FileListUploaded ="C\\Documents\\report.txt";
string parameter1 = "{\"startInfo\": {\"ReleaseKey\": \"xxxxx-xxx-xxx-xxx-xxxxxx\"," +
"\"RobotIds\": [xxxxx]," +
"\"JobsCount\": 0," +
"\"InputArguments\": \"{ "+
"\\\"reports_or_other_files\\\": \\\" + FileListUploaded + \\\"}\"}}";
request_startRobot.AddParameter("application/json; charset=utf-16", parameter, ParameterType.RequestBody);
IRestResponse response_startRobot = client_startRobot.Execute(request_startRobot);
That's a bit messy to look at, but it appears you are not quoting and escaping your JSON correctly.
I might suggest building an array and serializing it into JSON to make it easier to read, or using a HEREDOC or string formatting. If you do continue to concatenate your JSON body string together, dump out the results to see how it is coming together.
The final results of the JSON should look something like
{
"startInfo": {
"ReleaseKey":"{{uipath_releaseKey}}",
"Strategy":"JobsCount",
"JobsCount":1,
"InputArguments":"{\"reports_or_other_files\":\"C:\\\\Documents\\\\report.txt\"}"
}
}
With the InputArguments:
Looks like you are missing some quotes
Might need to double escape your backslashes in the FileListUploaded variable
Missing a colon after the C in the path
I'm not able to reverse a string in KIBANA/painless (section: scripted fields)
def foo = ('dlroW olleH');
return foo.reverse();
I expect the output of "Hello World", but KIBANA sais "No results found".
If i do a "return foo;" it works well - on every outputline "dlroW olleH" is shown.
Can anyone give me a hint, where the problem is?
EDIT: kibana 5.6, regexp for painless is disabled
.reverse() isn't a listed method to operate on a String object [1]; it's available to operate a StringBuffer object. [2]
You can make a StringBuffer and call reverse on it.
StringBuffer foo = new StringBuffer('dlroW olleH');
foo.reverse();
return foo.toString();
I want to write a test to check if a webelement with a specified text is not present on a page. This is the code for the method doing the job:
public boolean checkOfAanvraagIsOpgevoerd (String titel)
{
String quote = "\"";
String titelMetQuotes = quote + titel +quote;
titelMetQuotes = "dierdieboeboe";
boolean isOpgevoerd=false;
try {
driver.findElement(By.xpath(".//*[#id='listRequests']//h4/a[contains(text(),"+titelMetQuotes+")]"));
isOpgevoerd=true;
} catch (NoSuchElementException NE) {
NE.printStackTrace();
}
return isOpgevoerd;
}
Although I'm absolutely sure that there is no a tag on the page wich contains the text "dierdieboeboe" still the catch block is skipped. When I replace for instance h4 in h5 in the xpath expression the NoSuchElementException is thrown as expected. It seems that the contains part in the expression is ignored.
Try this (note the single quotes around the actual text):
By.xpath("//*[#id='listRequests']//h4/a[contains(text(),'"+titelMetQuotes+"')]")
contains is a function that takes two strings. Hence the text of your variable titelMetQuotes needs to be quoted. Obviously, in this case it is easier to use single quotes.
Additionally, the variable name (titel with quotes) is quite misleading because it actually has no quotes for another flaw in the code:
String titelMetQuotes = quote + titel +quote;
titelMetQuotes = "dierdieboeboe";
The second line simply overwrites the quoted title with a non quoted string.
Finally, you don't need the leading dot in your xpath expression in order to locate the first element of any kind with id listRequests
I'd like to condence the following code into fewer calls to .replace(). It doesn't look like .replace() will do this. Am I right or am I just reading the documentation wrong?
public void setBody(String body) {
this.body = body.replace("“", "\"").replace("”", "\"").replace("—", "-").replace("’", "'").replace("‘", "'");
}
You should be able to use body.replace(['"', '—', '‘'], ['\"', '-', "'"]).
You are right. To solve this, you should create a StringBuilder and go through your string 1 character at a time, adding the character to the stringBuilder if it is correct or replacing if it is wrong.