How to write an xpath for a dynamic URL - java

The below is the xpath I have written for
//form[#data-validate-url='/se/register/validate']
But the field data-validate-url changes from time to time e.g
data-validate-url= /gb/register/validate
data-validate-url= /de/register/validate
So, how to write an xpath having dynamic content. Please help

you can simply write this xpath using contains() function as below:
//form[contains(#data-validate-url,'/register/validate')]

In your url the dynamic part seems /gb , /de and rest of things are constant Use the CSS locator in following way to handle the same
driver.findElement(By.cssSelector("form[data-validate-url$='register/validate']"));
Also look into these
css=form[data-validate-url^='prefix_']
css=form[data-validate-url$=' _suffix']
css=form[data-validate-url*='_pattern_']

Related

how to use the count() function to get an element with a specific number of inner tags

I am using Java and Selenium to write a test. In my DOM, I have two svg tags. One of them has more that 2 inner path tags. I need to get this svg so I used:
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(
"//*[local-name() = 'svg' and count(.//path)>'2']")));
or
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(
"//*[local-name() = 'svg'] [count(.//path)>'2']")));
but it doesn't work. I need to know what's wrong with that so please do offer other ways around. Thanks.
by the way it worked for:
//*[local-name() = 'svg' and count(.//*[local-name() = 'path' ])>'1']
or
//*[local-name() = 'svg'][ count(.//*[local-name() = 'path' ])>'1']
The problem is you are trying to find .//path which is SVG element. As far as I know, you cannot do this because SVG elements are from different namespace. As you mentioned in your question, you can fix it by using [local-name() = 'path' ]. A workaround is using JSExecutor to execute method document.evaluate() so you can specify namespace of SVG. See example at this post.

How to get text from specific tag in XML using Java?

I have an xml which web resource and I have String to URL where the xml is and in it I have to find specific tag someTag and to get its text content. How to do it in java?
I search but only find ways where there is specific XPath,but in my case I do not know where someTag can be. Which parser to use? And how to implement it?
An XPath expression starting with a double slash will find an element anywhere:
XPathExpression xpw = xpath.compile( "//someTag" );
I recently used transformer class to process stix xml messages.
http://docs.oracle.com/javase/7/docs/api/javax/xml/transform/Transformer.html

How can I use XPath to resolve the following 'tags' values?

The xml file is :
<xml-fragment xmlns:xyz="http://someurl">
<xyz:xyzcontent>
<contentattribute>
<key>tags</key>
<value>tag1, tag2</value>
</contentattribute>
</xyz:xyzcontent>
...
I've tried the following:
XPathExpression createdDateExpression = xpath.compile("/contentattribute/key/attribute::tags/value");
There are several problems with your query.
The XML is broken (root tag not closed) -- probably just a copy/paste mistake
You're starting somewhere right in the middle of the XML tree, but actually try to query from the root node. Use the descendant-or-self-axis // in the beginning.
Which attribute are you querying using the attribute-axis? There is none.
Where did you register the namespaces? What namespace is xyz, anyway? I guess it's actually vp, but you obfuscated incompletely (or are not giving all relevant parts of the document).
Use predicates and string comparison to filter at axis steps.
Try following:
Make sure to register the namespace, have a look at the reference for that (or give more information).
Use the XPath query //contentattribute[key='tags']/value

With camel, how do I use the value of a header to define an XPath expression?

I have a header which has an XPath definition in it:
myXPath = "/bookshop/author/books/1|/bookshop/author/books/2"
and I'd then like to use this in an Xpath expression to set another header something like this:
<setHeader headerName="authorBooks">
<xpath resultType="org.w3c.dom.NodeList">${in.header.myXPath}</xpath>
</setHeader>
Reading the docs it seems you can use header values as part of your expression, but not to define the whole thing? I tried this and it didn't work:
<xpath resultType="org.w3c.dom.NodeList">in:header('myXPath')</xpath>
Anyone know of a way of doing this? I found this bug which seems to do what I want, but it's not slated to get fixed until 3.0:
https://issues.apache.org/jira/browse/CAMEL-3697
As almost always with Camel, when the DSL is limited for your situation, you can switch to doing this specific part in a plain Java processor/bean.
You can use the XPathBuilder to execute your expression and manually retreive the header.
Psuedocode:
String result = XPathBuilder.xpath(exchange.getIn().getHeader("myXpath",String.class)).evaluate(context, exchange.getIn().getBody());
In Camel 2.11 this is easier as you can do xpath directly on headers. See the official documentation at the section Using XPath on Headers.

Using XPath in XMLObject to query by namespace

I have a simple XML document
<abc:MyForm xmlns:abc='http://myform.com'>
<abc:Forms>
<def:Form1 xmlns:def='http://decform.com'>
....
</def:Form1>
<ghi:Form2 xmlns:ghi='http://ghiform.com'>
....
</ghi:Form2>
</abc:Forms>
</abc:MyForm>
I'm using XMLObjects from Apache and when I try to do the following xpath expression it works perfectly
object.selectPath("declare namespace abc='http://myform.com'
abc:Form/abc:Forms/*");
this gives me the 2 Form nodes (def and ghi). However I want to be able to query by specifying a namespace, so let's say I only want Form2. I've tried this and it fails
object.selectPath("declare namespace abc='http://myform.com'
abc:Form/abc:Forms/*
[namespace-uri() = 'http://ghiform.com']");
The selectPath returns 0 nodes. Does anyone know what is going on?
Update:
If I do the following in 2 steps, then I can get the result that I want.
XmlObject forms = object.selectPath("declare namespace abc='http://myform.com'
abc:Form/abc:Forms")[0];
forms.selectPath("*[namespace-uri() = 'http://ghiform.com']");
this gives me the ghi:Form node just like it should, I don't understand why it doesn't do it as a single XPath expression though.
Thanks
The simple answer is that you can't. The namespace prefix is just a shorthand for the namespace URI, which is all that matters.
For a namespace-aware parser, your two tags are identical.
If you really want to differentiate using the prefix (although you really, really shouldn't be doing it), you can use a non namespace-aware parser and just treat the prefix as if it was part of the element name.
But ideally you should read a tutorial on how namespaces work and try to use them as they were designed to be used.

Categories