Element created with XSLT templating not visible by Selenium - selenium

The problem is that when I try to set a value to an input, selenium return the following error:
RuntimeError: Element is not currently visible and so may not be interacted with
Howhever, the input is completly visible. In this test I'm using Firefox because is the browser where the application is correctly loaded.
I can't change the application code and the app has a lot of legacy code but I have recreated the most simple example where you can see the issue.
Do you know any workaround without modifying the application code?
I'm using webdriverio:
this.browser
.url('http://localhost/main.xml')
.setValue('[name=inputId]', 'aaaaaaaa')
.close()
.then(callback)
main.xml content:
<?xml version="1.0" encoding="iso-8859-1" ?>
<?xml-stylesheet type="text/xsl" href="main.xsl" ?>
<CONTEXTO></CONTEXTO>
main.xsl content:
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="iso-8859-1"/>
<xsl:include href="helper.xsl"/>
<xsl:template match="CONTEXTO">
<html>
<head>
<title>Test main</title>
<style>
* { margin:0; }
form { position: absolute; }
input { border: 1px black solid; }
</style>
</head>
<body>
<form name="" action="" method="POST">
<label for="inputId">inputId
<input type="text" name="inputId" id="inputId" value="" />
</label>
</form>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
helper.xsl content:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<script></script>
<xsl:apply-templates select="CONTEXTO"/>
</xsl:template>
</xsl:stylesheet>

Perhaps you have hit a limitation with Selenium with XML content, as it is treated differently by browsers than HTML content. You can try to fix this by using SendKeys instead. But if it cannot find the element, you will have to get to the element by key navigation, which can be tricky.
Alternatively, try finding the element with find_element_by_name or find_element_by_id or use XPath or this webdriver.io alternative. If none work, you can find out by traversing the tree from root node to the next. If none work, then my guess is, that Selenium sees the XML DOM (try to find the root element), not the XSLT-generated DOM.

Trying waiting for the input value to exist first:
.waitForExist('[name=inputId]', 1000)
.setValue('[name=inputId]', 'aaaaaaaa')

The problem is that the XSL is generating a malformed HTML. The helper is going to match / and generate a script tag and apply the CONTEXTO template, leading to a document such as:
<script></script>
<html>....</html>
That doesn't have too much sense as HTML.
For some reason firefox's TransformiIX engine in this situation is ignoring the output method HTML and is falling back to text output, which leads to the inclusion of a wrapper tag called transformiix:result. (see this link for reference).
You can check this, like I did, by issuing a getPageSource() to the webdriver and printing it to the log. You'll see the resulting output of the transformation is:
<transformiix:result>
<script></script>
<html>....</html>
</transformiix:result>
This is making webdriver be totally unable to interact with the page.
The recommended way to solve it is to fix the XSLT. If that's not an option (very big impact), the you can execute the following script using webdriver's executeScript, right after the page load (or before the first interaction attempt with the page).
document.getRootNode().replaceChild(document.getElementsByTagName('html')[0], document.getElementsByTagName('transformiix:result')[0])
This will replace the documents root node transformiix:result when present with the html tag.
Note that if in your current development, you have more stuff included by your helper.xsl, you might need to also take those tags and move then inside the header tag as part of the script above.
Edit: You can also reproduce the XSL issue by executing the following code in a firefox debug window:
//Execute in a firefox inspect console
var p = new XSLTProcessor();
var toTransform = document.implementation.createDocument(null, "CONTEXTO");
var parser = new DOMParser();
var xmlString = `<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="iso-8859-1"/>
<xsl:template match="/">
<script></script>
<xsl:apply-templates select="CONTEXTO"/>
</xsl:template>
<xsl:template match="CONTEXTO">
<html>
<body>
Hello
</body>
</html>
</xsl:template>
</xsl:stylesheet>
`;
p.importStylesheet(parser.parseFromString(xmlString, "text/xml"));
var doc = p.transformToDocument(toTransform);
console.log(doc.getRootNode().children[0].outerHTML);

Related

How to read Data from a file using XSLT in IBM API connect

I am working on creating REST API's in IBM API connect. our requirement is to get the backend URL's from a property file which is present on the datapower gateway server and then invoke the back-end service in the API's.
In API assembly I have written the XSLT code to open the file and read the data from the file, but the xslt is returning an empty response.
XSLT Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:func="http://exslt.org/functions"
xmlns:apim="http://www.ibm.com/apimanagement"
extension-element-prefixes="dp func apim"
exclude-result-prefixes="dp func apim">
<!-- Cotains the APIM functions -->
<xsl:import href="local:///isp/policy/apim.custom.xsl"/>
<xsl:template match="/">
<xsl:variable name="FileContent">
<dp:url-open target="'https://localhost:9090/dp'" response="xml" data-type="filename">local:///policy/propertyfiles/URLs.xml
</dp:url-open>
</xsl:variable>
<xsl:variable name="policy-props" select="apim:policyProperties()"/>
<xsl:variable name="catalog" select="apim:getContext('env.path')"/>
<outputXml>
<data><xsl:copy-of select="$FileContent" /></data>
<catalog><xsl:value-of select="$catalog" /></catalog>
<xsl:for-each select="$FileContent/catalogs/catalog">
<xsl:variable name="ReferencedID" select="#name"/>
<xsl:choose>
<xsl:when test="$ReferencedID = $catalog">
<backend_url><xsl:value-of select="$FileContent/response/catalogs/catalog/backend_url" /></backend_url>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</outputXml>
</xsl:template>
</xsl:stylesheet>
I am expecting to see the data from the file in the xslt response . But I see the below response which is missing the data from the file.
Body:
<?xml version="1.0" encoding="UTF-8"?>
<outputXml>
<data/>
<catalog>sb</catalog>
</outputXml>
Either use dp:url-open or possibly the document() function.
Another option is to add a GWS action to read the file and set it in a context variable.
Use below XSLT code it will capture Reques-
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dp="http://www.datapower.com/extensions"
xmlns:json="http://www.ibm.com/xmlns/prod/2009/jsonx"
xmlns:func="http://exslt.org/functions"
xmlns:apim="http://www.ibm.com/apimanagement" extension-element-prefixes="dp func apim" exclude-result-prefixes="xsl dp func apim">
<!-- Contains the APIM functions -->
<xsl:import href="local:///isp/policy/apim.custom.xsl" />
<xsl:template match="/">
<xsl:variable name="input" select="apim:payloadRead()" />
<xsl:message>
The input payload is
<xsl:copy-of select="$input" />
</xsl:message>
</xsl:template>
</xsl:stylesheet>

XProc: XD0001 It is a dynamic error if a non-XML resource is produced on a step output or arrives on a step input

Requirement: Is to add correct Doctype declaration on the output xml [The root element of the input xml can be chapter or section element]
Input XML: chapter.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd">
<chapter>
<title>Chapter Template Title</title>
<para>Text</para>
<section>
<title>Section Title</title>
<para>Section text</para>
</section>
</chapter>
XSLT file: test.xsl:
Stylesheet just copies input xml to output and adds #sec on all
element
Stylesheet adds correct doctype declaration to output xml, because
the input xml root element can be <chapter> or
<section> element
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template name="add-doctype-declaration">
<xsl:choose>
<xsl:when test="/chapter">
<xsl:text disable-output-escaping="yes">
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd">
</xsl:text>
</xsl:when>
<xsl:when test="/section">
<xsl:text disable-output-escaping="yes">
<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd">
</xsl:text>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="/">
<xsl:call-template name="add-doctype-declaration"/>
<xsl:apply-templates/>
</xsl:template>
<!-- Identity Template -->
<xsl:template match="#*|*|processing-instruction()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="section">
<xsl:copy>
<xsl:apply-templates select="#*"/>
<xsl:attribute name="sec">
<xsl:number/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Expected output.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "docbookx.dtd">
<chapter>
<title>Chapter Template Title</title>
<para>Text</para>
<section sec="1">
<title>Section Title</title>
<para>Section text</para>
</section>
</chapter>
Using any XSLT engine, the transformation works absolutely fine, and able to get the expected output
But, if the transformation is done through XProc I end up with the following error. Can someone help in resolving this error
err:XD0001 : XD0001 It is a dynamic error if a non-XML resource is
produced on a step output or arrives on a step input.
XProc file: test.xpl
<?xml version="1.0" encoding="UTF-8"?>
<p:declare-step xmlns:p="http://www.w3.org/ns/xproc"
xmlns:c="http://www.w3.org/ns/xproc-step" version="1.0" name="testing">
<p:input port="source">
<p:document href="chapter.xml"/>
</p:input>
<p:output port="result">
<p:empty/>
</p:output>
<p:xslt version="1.0" name="transform">
<p:input port="stylesheet">
<p:document href="test.xsl"/>
</p:input>
<p:input port="parameters">
<p:empty/>
</p:input>
</p:xslt>
<p:store omit-xml-declaration="false" encoding="utf-8" name="serialize">
<p:with-option name="href" select="output.xml"/>
</p:store>
</p:declare-step>
Here is two simple examples that shows that you don't need to contextualize the Doctype generation
Section
http://www.sharexml.com/x/get?k=uWn0KA7RThnt
Chapter http://www.sharexml.com/x/get?k=wAJlbUJfzIYQ
Hope this helps
[UPDATED AFTER ANSWER]
And if you want that doctype change dynamically
Section http://www.sharexml.com/x/get?k=pBAwCds86RnQ
Chapter http://www.sharexml.com/x/get?k=JHEWghzgWIq1
Hope this helps
What goes wrong here is that the doctype you are creating here, is passed as part of the result of the XSLT step to the XProc engine. However, it is passed as character data outside the root element. XProc does not allow this.
There are actually two issues with approach:
Don't use disable-output-escaping unless you can't do anything else. The xsl:output instruction has perfect means to create the doctype you want, just add a public-doctype and system-doctype attribute to it.
output options of the XSLT will be ignored, as the result isn't actually being serialized by the XSLT engine, but by XPRoc. So you will have to put those doctype attribute on the p:store step, to make it work within XProc.
HTH!

Xslt to copy inner xml without unused namespaces

I wish to remove a couple of unused namespaces from a resulting output from an xslt stylesheet.
The xml to feed in is a wrapper around another xml message which is seen in the BodyMessage element. An example of the entire xml can bee seen below:
<?xml version="1.0" encoding="utf-8"?>
<ns0:Wrapper xmlns:ns0="http://ref.fairyliquidplc.ads/Schema/Fairy/Wrapper/1.0" xmlns:mco="http://ref.fairyliquidplc.ads/Schema/Fairy/Common/1.0">
<TaskName>SomeTaskName</TaskName>
<TaskStatus>Start</TaskStatus>
<Id>Y/0070/0010</Id>
<BodyMessage>
<tva:TVAMain rightsOwner="FAIRY" xmlns:tva="urn:tva:metadata:2004">
<tva:Colour>red</tva:Colour>
<tva:Size>12</tva:Size>
<tva:Style>Skinny</tva:Style>
<tva:Fabric>Denim</tva:Fabric>
</tva:TVAMain>
</BodyMessage>
</ns0:Wrapper>
When I try to extract the xml out of the BodyMessage element I get unused namespaces returned
xmlns:ns0="http://ref.fairyliquidplc.ads/Schema/Fairy/Wrapper/1.0"
xmlns:mco="http://ref.fairyliquidplc.ads/Schema/Fairy/Common/1.0"
These are not required but I do not understand how to remove them within my xslt.
Please note I DO want to keep
xmlns:tva="urn:tva:metadata:2004"
The stylesheet I used is:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tva="urn:tva:metadata:2004"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns="http://www.w3.org/1999/xhtml">
<xsl:output encoding="UTF-8" method="xml" omit-xml-declaration="no" version="1.0" />
<xsl:template match="/">
<xsl:variable name="completeTva" select="//tva:TVAMain" />
<xsl:copy-of select ="$completeTva"/>
</xsl:template>
The output of the stylesheet is:
<?xml version="1.0" encoding="utf-8"?>
<tva:TVAMain rightsOwner="FAIRY" xmlns:tva="urn:tva:metadata:2004" xmlns:ns0="http://ref.fairyliquidplc.ads/Schema/Fairy/Wrapper/1.0" xmlns:mco="http://ref.fairyliquidplc.ads/Schema/Fairy/Common/1.0">
<tva:Colour>red</tva:Colour>
<tva:Size>12</tva:Size>
<tva:Style>Skinny</tva:Style>
<tva:Fabric>Denim</tva:Fabric>
What I require is:
<?xml version="1.0" encoding="utf-8"?>
<tva:TVAMain rightsOwner="FAIRY" xmlns:tva="urn:tva:metadata:2004">
<tva:Colour>red</tva:Colour>
<tva:Size>12</tva:Size>
<tva:Style>Skinny</tva:Style>
<tva:Fabric>Denim</tva:Fabric>
Any help would be greatly appreciated.
:)
This transformation (Sorry, this is a bug in the SO code-formatter!):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tva="urn:tva:metadata:2004"
xmlns:ns0="http://ref.fairyliquidplc.ads/Schema/Fairy/Wrapper/1.0"
xmlns:mco="http://ref.fairyliquidplc.ads/Schema/Fairy/Common/1.0"
>
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vtoDiscard" select=
"document('')
/*/namespace::*[name()='ns0' or name()='mco']"/>
<xsl:template match="tva:*">
<xsl:element name="{name()}"
namespace="urn:tva:metadata:2004">
<xsl:copy-of select="namespace::*[not(. = $vtoDiscard)]"/>
<xsl:copy-of select="#*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="text()[not(ancestor::BodyMessage)]"/>
</xsl:stylesheet>
when applied on the provided XML document:
<ns0:Wrapper
xmlns:ns0="http://ref.fairyliquidplc.ads/Schema/Fairy/Wrapper/1.0"
xmlns:mco="http://ref.fairyliquidplc.ads/Schema/Fairy/Common/1.0">
<TaskName>SomeTaskName</TaskName>
<TaskStatus>Start</TaskStatus>
<Id>Y/0070/0010</Id>
<BodyMessage>
<tva:TVAMain rightsOwner="FAIRY"
xmlns:tva="urn:tva:metadata:2004">
<tva:Colour>red</tva:Colour>
<tva:Size>12</tva:Size>
<tva:Style>Skinny</tva:Style>
<tva:Fabric>Denim</tva:Fabric>
</tva:TVAMain>
</BodyMessage>
</ns0:Wrapper>
produces the wanted, correct result:
<tva:TVAMain xmlns:tva="urn:tva:metadata:2004" rightsOwner="FAIRY">
<tva:Colour>red</tva:Colour>
<tva:Size>12</tva:Size>
<tva:Style>Skinny</tva:Style>
<tva:Fabric>Denim</tva:Fabric>
</tva:TVAMain>
Explanation:
Both xsl:copy and xsl:copy-of copy an element together with the namespace nodes that belong to it.
The way to strip some namespace nodes off an element is to re-create it using the xsl:element, then to copy from the original element only the wanted namespace nodes.

using bing api xslt

I'm trying to use the Bing Image api, but can't manage to get it working.
I'm trying to transform the result, but the transformation does not return anything useful.
I think this is because I'm doing something wrong with the namespaces, as it is something I find terribly confusing in all xml related languages...
here is an example of what I receive from Bing:
<?xml version="1.0" encoding="utf-8" ?>
<?pageview_candidate?>
<SearchResponse xmlns="http://schemas.microsoft.com/LiveSearch/2008/04/XML/element" Version="2.2">
<Query>
<SearchTerms>natalie portman</SearchTerms>
</Query>
<mms:Image xmlns:mms="http://schemas.microsoft.com/LiveSearch/2008/04/XML/multimedia">
<mms:Total>644000</mms:Total>
<mms:Offset>0</mms:Offset>
<mms:Results>
<mms:ImageResult>
<mms:Title>Natalie Portman/natalie-portman-83</mms:Title>
<mms:MediaUrl>http://www.bestidol.pl/natalieportman/slides/natalie-portman-83.jpg</mms:MediaUrl>
<mms:Url>http://www.bestidol.pl/natalieportman/slides/natalie-portman-83.php</mms:Url><mms:DisplayUrl>http://www.bestidol.pl/natalieportman/slides/natalie-portman-83.php</mms:DisplayUrl>
<mms:Width>1024</mms:Width>
<mms:Height>768</mms:Height>
<mms:FileSize>95173</mms:FileSize>
<mms:ContentType>image/jpeg</mms:ContentType>
<mms:Thumbnail>
<mms:Url>http://ts1.mm.bing.net/images/thumbnail.aspx?q=809383506038& amp;id=b829ae4c6df8866b6a07325bedca4bbd</mms:Url>
<mms:ContentType>image/jpeg</mms:ContentType>
<mms:Width>160</mms:Width>
<mms:Height>120</mms:Height>
<mms:FileSize>3838</mms:FileSize>
</mms:Thumbnail></mms:ImageResult>
<mms:ImageResult>
... other ImageResults and closing tags.
here my curent xslt transformation:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:mms="http://schemas.microsoft.com/LiveSearch/2008/04/XML/multimedia">
<xsl:template match="/">
<list>
<xsl:for-each select="//mms:ImageResult" >
<element>
<image>
<url><xsl:value-of select="/mms:MediaUrl" /></url>
<width><xsl:value-of select="/mms:Width" /></width>
<height><xsl:value-of select="/mms:Height" /></height>
</image>
</element>
</xsl:for-each>
</list>
</xsl:template>
</xsl:stylesheet>
does somebody see my mistake(s)?
because this transform returns me:
<list xmlns:mms="http://schemas.microsoft.com/LiveSearch/2008/04/XML/multimedia">
<element>
<image>
<url/>
<width/>
<height/>
</image>
</element>
...
</list>
Shoudnt be...
<url><xsl:value-of select="mms:MediaUrl" /></url>
<width><xsl:value-of select="mms:Width" /></width>
<height><xsl:value-of select="mms:Height" /></height>
?

XPath when a root node and element have different Name Space attributes

I got struck with a problem in VB.Net getting Xpath for an XML element as shown below:
<Parent xmlns:"http://www.sample.com">
<body>
<Child xmlns:"http://www.notsample.com">
<element type="xyz"> ghghghghghg </element>
</Child>
</body>
</Parent>
I need Xpath of the "element" in above XML using VB.Net NameSpace Manager
For the "body" node i have done and its working but i couldnt do the same to "element":
dim bodynode as XMLNode=XML.SelectSingleNode(//ns:body,nsmngr)
where "nsmngr" is the namespacemanger created by me and "ns" is the name space of the "parent node" (which the "body" node inherits) added to the namespace manager as "ns"
Thanks
Kiran
There are two different ways to construct the needed XPath expression:
Define a second namespace binding with NamespaceManager, say ns2: bound to http://www.notsample.com. Then use:
/*/ns:body/ns2:Child/ns2:element
Don't use namespaces at all:
/*/*[name()='body']/*[name()='Child']/*[name()='element']
Given the following xml:
<OuterElem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:test="http://www.w3.org/2001/XMLSchema-instance1" xmlns:test1="http://www.w3.org/2001/XMLSchema-instance1">
<test:parent>
<test1:child1>blabla1</test1:child1>
<test1:child2>blabla2</test1:child2>
<test:child2>blabla3</test:child2>
</test:parent>
<test1:child1>blabla4</test1:child1>
</OuterElem>
the following xslt (xslt 1.0) copies all nodes except "test:parent/test1:child1":
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:test="http://www.w3.org/2001/XMLSchema-instance1" xmlns:test1="http://www.w3.org/2001/XMLSchema-instance1">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="test:parent/test1:child1"/>
</xsl:stylesheet>
The result will be:
<OuterElem xmlns:test="http://www.w3.org/2001/XMLSchema-instance1" xmlns:test1="http://www.w3.org/2001/XMLSchema-instance1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<test:parent>
<test1:child2>blabla2</test1:child2>
<test:child2>blabla3</test:child2>
</test:parent>
<test1:child1>blabla4</test1:child1>
</OuterElem>