Escaping special characters inside XPATH - xpath

I have some elements with the tag <xxx:element> inside my xml.
I want to get these using XPath. I've tried a few ways of getting them but so far unsuccessful.
//xxx:element just doesn't return anything. I'm guessing this is because of the : characater
//#xxx:element# gives the exception: "A location step was expected following the '/' or '//' token."
//'xxx:element' same exception.
Any suggestions?
Based on choroba's answer I found Xml Namespace breaking my xpath!

The xxx: part is a namespace prefix. It should work in XPath, but depending on the language you are using, you might need to register the namespace before you can use it.

Found a solution using the local-name property. The following works just fine:
//*[local-name()='element']

In saxon //*:element do the trick to me

Related

Escape single quote in Xtend template expression

I have a very simple question, but could not figure it out by Google search, please help.
I want to produce this string '\u0000' (note the simple quote marks surrounding it!) using the following simple Xtend method containing a template expression:
def String makeDefaultChar()
{
''''\u0000''''
}
However, this is not accepted as proper syntax (probably because of the four ''''. Is there an escape character for this use case or what is the right syntax?
Thank you in advance!
P.S.
Of course I could use plain Java string like this "'\\u0000'" to achieve the same, but I want to use an Xtend template expression.
My Xtend version is: 2.9.1.v201512180746
There is no "escaping" in template expressions, so you have to use the workaround you mentioned:
'''«"'\\u0000'"»'''
or
'''«"'"»\u0000«"'"»'''
Related discussion: https://groups.google.com/forum/#!topic/xtend-lang/bVZ0nKmQGAI
Single quotes are allowed within Xtend templates as long as they do not occur at the beginning or the end of the template. So a simple workaround is to add an empty expression before/after the single quote:
'''«»'\u0000'«»'''

XPath text() expression - what to specify in text() if it contains newline

The text is as:
text1text2
How can I specify this text in xpath. I tried:
.//*[#id='someid']//h6[text() ='text1text2]
.//*[#id='someid']//h6[text() ='text1\ntext2]
.//*[#id='someid']//h6[text() ='text1 text2]
None of them worked
Use .//*[#id='someid']//h6[. = 'text1
text2']. This assumes you are writing the path inside of XSLT or XForms where you can use
to escape a new line character. If you are not using XSLT you might want to tell us in which host language (e.g. PHP, C#, Java) you use XPath.
not very elegant but it works
.//*[#id='someid']//h6[contains(text(), 'text1') and contains(text(), 'text2')]
You can use normalize-space() to remove the line feed and compare text without this issue.
//*[#id='someid']//h6[normalize-space(text()) ='text1 text2']
This is the working code
.//*[#id='someid']//h6[. = 'text1text2']
Thank you.

Howto embed a custom non-visible HTML5 data attribute in a Freemarker template?

I would like to define a custom data-* attribute in an Spring form tag:
<#form.input path="endDate" data-tralaaa="moin"/>
Unfortunately Freemarker doesn't like this. Anyone a clue? I get the following exception:
Caused by: freemarker.core.ParseException: Encountered "-" at line 24, column 114 in WEB-INF/views/reisenachsendung/period.ftl.
Was expecting:
"=" ...
I would like to produce a HTML5 valid page. So dataTralaaa is not an option.
Update: As of 2.3.22, you can use - (and . and :) as part of any name if you precede it with a \, like in <#form.input data\-tralaaa="moin">. (It's not too cute, but - is already used as subtraction operator, and fixing this wouldn't backward compatible, and so must wait for a major FTL version increase.)
The problem is that you can't use dash in parameter names. This is a syntactical restriction. But that's maybe only half of the problem. Does Spring's #form.input accept parameters that it doesn't know and inserts them into the HTML tag? Because if it doesn't, then the whole dash issue doesn't mater.

xpath to check '#' present

I want to write xpath to check node contain '#'
<node1>
<node11>Some text</node11>
<node11>#2o11 PickMe</node12>
</node1>
I want to write xpath like "//node11[contains(,'#\d+')]". Whats correct way to check #
The correct XPath expression is:
//node11[contains(., '#')]
In your XML, the closing tag of the second subnote should be </node11> instead of </node12>.
If you are using xpath 2.0 you should be able to use something like:
"//node11[matches(.,'#\d+')]"
However, if you aren't using 2.0 you won't have regex support directly. If you are using 1.0 then you won't be able to match using \d+. But this will work:
"//node11[contains(.,'#')]"
Or even:
"//node11[starts-with(.,'#')]"
Use:
/*/node11[contains(., '#')]
Note: It is recommended to avoid using the // pseudo-operator because this most often leads to very slow evaluation of the XPath expression.

Trouble using Xpath "starts with" to parse xhtml

I'm trying to parse a webpage to get posts from a forum.
The start of each message starts with the following format
<div id="post_message_somenumber">
and I only want to get the first one
I tried xpath='//div[starts-with(#id, '"post_message_')]' in yql without success
I'm still learning this, anyone have suggestions
I think I have a solution that does not require dealing with namespaces.
Here is one that selects all matching div's:
//div[#id[starts-with(.,"post_message")]]
But you said you wanted just the "first one" (I assume you mean the first "hit" in the whole page?). Here is a slight modification that selects just the first matching result:
(//div[#id[starts-with(.,"post_message")]])[1]
These use the dot to represent the id's value within the starts-with() function. You may have to escape special characters in your language.
It works great for me in PowerShell:
# Load a sample xml document
$xml = [xml]'<root><div id="post_message_somenumber"/><div id="not_post_message"/><div id="post_message_somenumber2"/></root>'
# Run the xpath selection of all matching div's
$xml.selectnodes('//div[#id[starts-with(.,"post_message")]]')
Result:
id
--
post_message_somenumber
post_message_somenumber2
Or, for just the first match:
# Run the xpath selection of the first matching div
$xml.selectnodes('(//div[#id[starts-with(.,"post_message")]])[1]')
Result:
id
--
post_message_somenumber
I tried xpath='//div[starts-with(#id,
'"post_message_')]' in yql without
success I'm still learning this,
anyone have suggestions
If the problem isn't due to the many nested apostrophes and the unclosed double-quote, then the most likely cause (we can only guess without being shown the XML document) is that a default namespace is used.
Specifying names of elements that are in a default namespace is the most FAQ in XPath. If you search for "XPath default namespace" in SO or on the internet, you'll find many sources with the correct solution.
Generally, a special method must be called that binds a prefix (say "x:") to the default namespace. Then, in the XPath expression every element name "someName" must be replaced by "x:someName.
Here is a good answer how to do this in C#.
Read the documentation of your language/xpath-engine how something similar should be done in your specific environment.
#FindBy(xpath = "//div[starts-with(#id,'expiredUserDetails') and contains(text(), 'Details')]")
private WebElementFacade ListOfExpiredUsersDetails;
This one gives a list of all elements on the page that share an ID of expiredUserDetails and also contains the text or the element Details

Resources