Make Nokogiri treat xmlns as an ordinary attribute? - ruby

I know how to work with namespaces in Nokogiri, but sometimes, I want to look at how the document is actually specified.
In those cases, it would be nice if Nokigiri could simply act like it knows nothing about namespaces, treat "xmlns" just like any other attribute, and treat elements as if their names are exactly as written (colons and all, when present) and all in the default namespace.
Is there a way to achieve that?
EDIT: Add example
So let's say I'm using Nokogiri to check generated SVG. I want to know that the namespace was specified in the root element using the xmlns attribute, and I want to know that the sub-elements use implicit name-spacing.
<svg version="1.1" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<path d="M 10,10 l 5,20" />
</svg>
If I parse that using Nokogiri, then I can find the "path" element as follows:
svg_doc.xpath('//ns:svg/ns:path', 'ns' => "http://www.w3.org/2000/svg")
That shows me that the file is "correct" in terms of resulting in elements with the expected namespaces, but doesn't let me know anything about how that namespacing was specified.
If I could get a document instance that is completely ignorant of namespaces, then…
I could inquire about the "xmlns" attribute value using svg_doc.root['xmlns']…
and I could find that there is a "path" element child of the "svg" root element and that neither element has namespace qualifier prefix using svg_doc.xpath('//svg/path').

In the "Namespaces" section of "Searching an HTML / XML Document" is the part about using CSS selectors:
Don’t be fooled though. You do not have to use XPath to get the benefits of namespaces. CSS selectors can be used as well. CSS just uses the pipe symbol to indicate a namespace search.
Let’s see the previous search rewritten to use CSS:
#doc.css('xmlns|title') # => ["<title>Example Feed</title>", "<title>Atom-Powered Robots Run Amok</title>"]
When using CSS, if the namespace is called “xmlns”, you can even omit the namespace name. That means your CSS will reduce to:
#doc.css('title') # => ["<title>Example Feed</title>", "<title>Atom-Powered Robots Run Amok</title>"]

Related

I have doubts about two mappings on the site-prism

I don't want to use xpath on the elements below.
element :img_login, :xpath, '//[#id="main-wrapper"]/div/section/div/div[2]/div/div/div[1]/img'
element :msg_login_senha_invalidos, :xpath, '//[#id="main-wrapper"]/div/section/div/div[2]/div/div/div[2]/div/p'
They are on the page as follows:
element img_login
<div class="sc-jRQAMF eRnhep">
<img src="https://quasar-flash-staging.herokuapp.com/assets/login/flashLogo-3a77796fc2a3316fe0945c6faf248b57a2545077fac44301de3ec3d8c30eba3f.png" alt="Quasar Flash">
</div>
element msg_login_senha_invalidos
<p class="MuiFormHelperText-root MuiFormHelperText-contained Mui-error MuiFormHelperText-filled">Login e/ou senha inválidos</p>
You have asked multiple questions about converting from using XPath to some other type of selector when using Site-Prism. StackOverflow is meant to be a place to come, learn, and improve your skills - not just to get someone else to do your work. It really seems you'd be better off reading up on CSS and how it can be used to select elements. Also note that there's nothing specifically wrong with using XPath, per se, it's just the way people new to testing and selecting elements on a page tend to use it (just copying a fully specified selector from their browser) that leads to having selectors that are way too specific and therefore brittle. A good site for you to learn about the different general CSS selector options available is https://flukeout.github.io/ - and you can look at the built-in selector types provided by Capybara at https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selector.rb#L18
In your current case the below may work, but with the HTML you have provided all that's possible to say is that they will match the elements shown however they may also match other elements which will give you ambiguous element errors.
element :img_login, :css, 'img[alt="Quasar Flash"]' # CSS attribute selector
element :msg_login_senha_invalidos, :css, 'p.Mui-error', text: 'Login e/ou senha inválidos' # CSS class selector combined with Capybara text filter

CSS selector for a single attribute out of multiple attributes

how do you select a single attribute within the element
<img src="xyz.jpg" title="xyz" alt="xyz">
just need the img src
seems to be an overlooked question
as all assumed implementations yield the entire tag still
Assuming your element is actually something like
<img src="xyz.jpg" title="xyz" alt="xyz">yo!</img>
the xpath expression
//img/#src
Should get you xyz.jpg.

Xpath: getting data by comparing attributes

I need to assign an XPath expression to а reference tag which will generate automated text near my reference. The generated text should be taken from the title of the target element(figure).
This is how it looks.
Reference construction(could be located anywhere)
<internalRef internalRefId="fig1"></internalRef>
figure construction(may be anywhere)
<figure id="fig1">
<title>The TEXT I TRY TO GET
</title>
...
</graphic>
</figure>
I guess i should take the "title in figure" tag content if the figure's id attribute matches the link's target attribute.
One of my fail expression variants that prints nothing
//figure[self/#internalRefId=#id]/title
Thanks for ideas...
You're searching for #internalRefId attributes inside some non-existent <self/> element. Use you write the <internalRef/> element "could be located anywhere", this should be fine:
//figure[//#internalRefId=#id]/title
This will return all title elements for figures that have an #id equal to any #internalRefId attribute anywhere in the document.

Replacing an attribute from within a tag

Consider this:
<img style="INFO" alt="INFO" src="INFO" target="INFO" onmouseout="INFO" />
How can I target every attribute (style, alt, src etc.) within the IMG tag to validate it against a white-list?
You should use a DOM parser for that. Depending on what language you are using there are different library that you can use for that.

SVG: Use Attributes or CSS to style?

In HTML it is recommended to seperate Content from Style, thus you should create external CSS-Files for your styles. As I am just getting started with SVG I now wonder: Does this rule also apply for SVG?
What is considered better code style?
<circle fill="yellow" />
or <circle style="fill: yellow;" />
I arrived here because I was trying to remember whether attributes or styles have greater precedence. This is one practical reason why you'd want one over another.
Attributes get applied as "presentation hints", as if they were the first of the cascading style sheets. In other words, this gives them lowest precedence.
Thus the precedence, from lowest to highest, is
attributes
CSS style sheets
inline styles
It's a little confusing that an inline style has much greater precedence than the attribute it's next to. (I keep having to look this up!)
There aren't going to be any new presentation attributes, and we are encouraged to use CSS styling instead, but it doesn't sound like presentation attributes are going away anytime soon.
More detail can be found in the Presentation Attributes section of the Styling chapter of the SVG standard.
I would generally prefer <circle fill="yellow" /> to <circle style="fill: yellow;" /> because it's shorter and easily to manipulate with, for example, getAttributeNS(null, "fill").
But over that I would prefer using a separate style element, just as with HTML, e.g:
<style>
circle{
fill: yellow;
}
</style>
Which has all the same advantages of using CSS, such as making it easy to change the stlye of lots of elements at once.
You can also put your CSS in an external file and add:
<?xml-stylesheet type="text/css" href="your_CSS.css" ?>
Before the svg element.
I have found Presentation Attributes vs Inline Styles on css-trick really useful for this.
From it:
The difference is always if it's content or it's presentation.
If the circle is content and it has to show whether or not there css available, then the first option is the one.
But if the circle is just part of the site disign and doesn't add anything to the content, then it should be the second option. Or use a css class.

Resources