vtd-xml replaceing whole element - vtd-xml

I run into strange problem and I cant find anything on web for that.
Im using xpath to locate my xml chunk and then replace it with something else ex:
// input
<html>
...
<style type="">
background: yellow;
</style>
<link href="path" />
</html>
// output
<html>
...
<link href="pathToFileWithBackground" />
<link href="path_other" />
</html>
I use XMLModifier to actually update token (using updateToken method :]) and it works for attributes manipulation or for text (body) of element.
I have problem with style element, I want to process its body and then replace whole element with link to some file.
obviously updating text token will result with style token with link tag inside it.
<style type=""><link href="path" />
</style>
so I tried moving navigator to style element and got this
<<link href="path" /> type="">
background: yellow;
</style>
I also tried inserting link element before style element and removing it but I got ModifyException("Invalid insertion/deletion condition detected between offset .. and offset") from XMLModifier when I try to save modifier's data. here is the code for that
ap.selectXPath("//style/text());
vn.toElement(VTDNav.PARENT);
modifier.insertBeforeElement(replaceString);
modifier.remove();
I tried to use remove(long l) and remove(int offset, int lengtt) version but got same exception
any ideas on that

OK so the problem was with
vn.getElementFragment()
returned wrong length. maybe because (in my test file) style element was followed by comments and comment characters were included and length was bigger than it should be
this fixed everything
int o = (int)vn.getElementFragment();
int l = (int)(vn.getElementFragment() >> 32);
final String s = new String(vn.getXML().getBytes(o, l));
l = s.substring(0, s.indexOf("</style>")+8).length(); // ;]
modifier.removeContent(o, l);
modifier.insertBeforeElement(replaceString);
hope it will help someone

Related

WinHTTP getElementsByTagName() only shows opening tag for "section"

Using AhtuHotkey 2.0 Beta1 (i assume VBA script as well) getElementsByTagName() only shows opening tag for HTML5 tags section and nav however works with all other HTML4 tags.
AutoHotkey Code
HTMLObj := ComObject("HTMLfile")
HTMLObj.write(HTML)
DOMObj := HTMLFileObj.getElementsByTagName("section")
msgbox DOMObj[0].outerHTML
following will return just opening tag <section class=mysection> i think it simply does not know how to handle HTML5 tags. Is there solution, i am on Windows 7 x64 Service Pack 1
Old versions of IE('s HTML parser) treat unknown elements as inline elements by default. That means the parser auto-closes them as soon the next known block element is encountered.
Try this (a bare-bones version of the much more comprehensive https://github.com/aFarkas/html5shiv):
html5shim =
(
<script>
document.createElement('header');
document.createElement('section');
document.createElement('main');
document.createElement('article');
document.createElement('aside');
document.createElement('nav');
document.createElement('footer');
</script>
)
HTMLObj := ComObject("HTMLfile")
HTMLObj.write(html5shim)
HTMLObj.write(HTML)
DOMObj := HTMLFileObj.getElementsByTagName("section")
msgbox DOMObj[0].outerHTML
An alternative way would be to add CSS that declares these elements as block elements:
<style type="text/css">
header, section, main, article, aside, nav, footer { display: block; }
</script>

Why won’t both of my html stuff work together

I am trying to decorate my background of my website I am building and for some reason I can put one or the other by themselves work but when I add both lines then only the top one works. How can I make both lines work together.
<body style=background-color:powderblue>
<body style=border-style:solid;border-color:red>
You can only have one <body> tag.
<body style="background-color:powderblue;border-style:solid;border-color:red">
Combine the styles into one, or move the styles to a css file or <style> block in your <head>
body {
background-color:powderblue;
border-style:solid;
border-color:red
}

C# Selenium Webdriver (Firefox) iFrame does not allow text to be entered via sendKeys

I'm using latest Selenium Firefox (2.53.0)
Previously code was working when performing the following
1) Finding the iFrame by Xpath iframe class
IWebElement detailFrame = `Driver_Lib.Instance.FindElement(By.XPath("//iframe[#class='cke_wysiwyg_frame cke_reset']"));`
2) Switching to that frame by
Driver_Lib.Instance.SwitchTo().Frame(detailFrame);
3) finding the p tag within the iFrame by
IWebElement freeText = Driver_Lib.Instance.FindElement(By.TagName("p"));
4) Inserting a simple string to the iframe text box
freeText.SendKeys("this is some text");
5) switching from the iFrame back to the main contentwindow by
Driver_Lib.Instance.SwitchTo().DefaultContent();
Here is the code part from the application
<iframe class="cke_wysiwyg_frame cke_reset" frameborder="0" src="" style="width: 100%; height: 100%;" title="Rich Text Editor, ctl00_ctl00_MainContentPlaceHolder_PageContent_mlcEditor_CKEditor" aria-describedby="cke_61" tabindex="0" allowtransparency="true">
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<title data-cke-title="Rich Text Editor, ctl00_ctl00_MainContentPlaceHolder_PageContent_mlcEditor_CKEditor">Rich Text Editor, ctl00_ctl00_MainContentPlaceHolder_PageContent_mlcEditor_CKEditor</title>
<style data-cke-temp="1">
<link href="https://myUrl/contents.css" rel="stylesheet" type="text/css">
<style data-cke-temp="1">
</head>
<body class="cke_editable cke_editable_themed cke_contents_ltr cke_show_borders" contenteditable="true" spellcheck="false">
<p>
<br _moz_editor_bogus_node="TRUE">
</p>
</body>
</html>
</iframe>
The test I am running is a simple one, open up that page, insert some text, save.
It not inserting the text into the iFrame. I am totally puzzled as to why.
Has anyone else found this issue at all?
Many thanks
I have removed the exception, this was a redHerring.
the iFrame can not have text entered into it
hi all I've found the solution:~ here is the summary of what was happening:
1) The iFrame was being located by xPath.
2) the SwitchTo() method used placed focus in the detailFrame instance of IWebElement
3) What was not happening was the p tag could not be located as it was contained withing a CSS Body Class that.
The solution was staring me in the face the whole time! so simple!!
I did this:
IWebElement detailFrame = Driver_Lib.Instance.FindElement(By.XPath("//iframe[#class='cke_wysiwyg_frame cke_reset']"));
Driver_Lib.Instance.SwitchTo().Frame(detailFrame);
IWebElement freeText = Driver_Lib.Instance.FindElement(By.TagName("body"));
freeText.SendKeys("This is a free text question created by Automation Smoke Test");
Driver_Lib.Instance.SwitchTo().DefaultContent();
So as you see, simply locating the 1st instance of the body tag!

Get a css property with selenium webdriver by selectors

I am doing a exercise with client java to use cssSelector method to retrieve some objects having a particular web element's CSS property.
The statement
driver.findElements(By.cssSelector(".item-result .content-main .block-opening"))
returns all elements from page using the class ".item-result .content-main .block-opening" (refer to my blocks below) and all is fine up to there!
Nevertheless, I only want those which have a property text-indent whose value is -999em. To perform it, I first use
driver.findElements(By.cssSelector(".item-result .content-main .block-opening[text-indent]"))
to retrieve all elements having a text-indent css property but I realize that no element is matching while I have text-indent property inside my css block.
HTML block
<html id="ng-app" data-ng-app="rwd" data-ng-controller="AppCtrl" lang="fr" class="ng-
scope">
<head>...</head>
<body>
...
<span class="block-opening icon-time-filled ng-scope" data-ng-if="bloc.openClosed ==
'O'">Ouvert</span>
...
</body>
</html>
CSS block
.item-result .content-main .block-opening {
width: 25px;
color: #a1a1a1;
text-indent: -999em;
}
I was hoping to find exactly what i want to by the use of
driver.findElements(By.cssSelector(".item-result .content-main .block-opening[text-indent='-999em']"))
Since elements related to text-indent are not found, I am blocked to find those having text-indent to -999em.
Please any help would be appreciated!
Perhaps a little bit of a longer route but you could try getting a list of all the elements and checking the css-properties, with the appropriate method.
List<Webelement> elements = driver.findElements(By.cssSelector(".item-result .content-main .block-opening"));
for (Webelement element : elements) {
if (element.getCssValue("text-indent").equals("-999em")) {
return element;
}
}
Caveat, I've never tried to get the text-indent value, as such I can't guarantee that the above will work.
http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/WebElement.html#getCssValue(java.lang.String)
You can locate that element using xpath using inner text value
By.xpath("//span[text()='Ouvert']")

How to add id using dojo.query to search element

I'm trying to add id to a element using dojo.query. I'm not sure if it's possible though. I trying to use the code below to add the id but it's not working.
dojo.query('div[style=""]').attr("id","main-body");
<div style="">
content
</div>
If this is not possible, is there another way to do it? Using javascript or jquery? Thanks.
Your way of adding an id to an element is correct.
The code runs fine for me in Firefox 17 and Chrome 23 but I have an issue in IE9. I suspect you may have the same issue.
In IE9 the query div[style=""] returns no results. The funny thing is,it works fine in compatibility mode!
t seems that in IE9 in normal mode if an HTML element has an inline empty style attribute, that attribute is not being preserved when the element is added to the DOM.
So a solution would be to use a different query to find the divs you want.
You could try to find the divs with an empty style attributes OR with no style attribute at all.
A query like this should work:
div[style=""], div:not([style])
Take a look at the following example:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test Page</title>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.8.2/dojo/dojo.js"></script>
<script type="text/javascript">
dojo.require("dojo.NodeList-manipulate");//just for the innerHTML() function
dojo.addOnLoad(function () {
var nodeListByAttr = dojo.query('div[style=""], div:not([style])');
alert('Search by attribute nodeList length:' + nodeListByAttr.length);
nodeListByAttr.attr("id", "main-body");
var nodeListByID = dojo.query('#main-body');
alert('Search by id nodeList length:' + nodeListByID.length);
nodeListByID.innerHTML('Content set after finding the element by ID');
});
</script>
</head>
<body>
<div style="">
</div>
</body>
</html>
Hope this helps
#Nikanos' answer covers the query issue, I would like to add, that any query returns an array of elements, in case of Dojo it is dojo/NodeList.
The problem is you are about to assign the same id to multiple DOM nodes, especially with query containing div:not([style]). I recommend to use more specific query like first div child of body:
var nodes = dojo.query('body > div:first-child');
nodes.attr("id", "main-body");
To make it more robust, do not manipulate all the nodes, just the first node (even through there should be just one):
dojo.query('body > div:first-child')[0].id = "main-body";
This work also in IE9, see it in action: http://jsfiddle.net/phusick/JN4cz/
The same example written in Modern Dojo: http://jsfiddle.net/phusick/BReda/