XPath Powershell query for a string - powershell

I'd like to know how to search for a string within an xml document. The object type is System.Xml.XmlNode.XmlDocument. The string can be anything with the document. I.e. attribute or element.
I tried
Select-Xml -Xml $xml -XPath "./Test"
but got no results

The pattern you are trying to use selects root nodes named Test.
You could use the pattern (//text()|//#*)[contains(string(), "test")], that selects the attributes that contain the string test or the text nodes that contain it (i.e. not the elements).
But you want to select the elements, right? Using (//*|//#*)[contains(., "test")] does that, but it selects elements that contain the string test, even if it is through some child element, which is not what is wanted either.
So I guess you'll have to use something like (//*[contains(text(), "test")]|//#*[contains(., "test")]), which gives you what you want, but is not very pretty.

Related

How to get the values of an element by name

I am using T-SQl and xPath to query an xml doc. and I need to extract the value of an element by name
This is the way I initially implemented the code "using element indexing to access the element" but since element can have multiples element of , it does not longer work properly.
n.value(''./ROLES[1]/ROLE[1]/BORROWER[1]/GOVERNMENT_MONITORING[1]/HMDA_RACES[1][./HMDA_RACE/EXTENSION/ULDD:OTHER/ULDD:HMDA_RACE_EXTENSION/ULDD:HMDA_RACE_DETAIL/ULDD:HMDARaceType][1]'',''VARCHAR(100)'')
This is the xml I am querying
<HMDA_RACES>
<HMDA_RACE>
<EXTENSION>
<ULDD:OTHER xmlns:ULDD="http://www.datamodelextension.org/Schema/ULDD">
<ULDD:HMDA_RACE_EXTENSION>
<ULDD:HMDA_RACE_DESIGNATIONS>
<ULDD:HMDA_RACE_DESIGNATION>
<ULDD:HMDARaceDesignationType>Samoan</ULDD:HMDARaceDesignationType>
</ULDD:HMDA_RACE_DESIGNATION>
</ULDD:HMDA_RACE_DESIGNATIONS>
<ULDD:HMDA_RACE_DETAIL>
<ULDD:HMDARaceType>NativeHawaiianOrOtherPacificIslander</ULDD:HMDARaceType>
</ULDD:HMDA_RACE_DETAIL>
</ULDD:HMDA_RACE_EXTENSION>
</ULDD:OTHER>
</EXTENSION>
</HMDA_RACE>
<HMDA_RACE>
<EXTENSION>
<ULDD:OTHER xmlns:ULDD="http://www.datamodelextension.org/Schema/ULDD">
<ULDD:HMDA_RACE_EXTENSION>
<ULDD:HMDA_RACE_DETAIL>
<ULDD:HMDARaceType>White</ULDD:HMDARaceType>
</ULDD:HMDA_RACE_DETAIL>
</ULDD:HMDA_RACE_EXTENSION>
</ULDD:OTHER>
</EXTENSION>
</HMDA_RACE>
</HMDA_RACES>
this is what I am trying but I am not getting the result I want.
value(''./ROLES[1]/ROLE[1]/BORROWER[1]/GOVERNMENT_MONITORING[1]/HMDA_RACES[child = "ULDD:HMDARaceType"][1]'',''VARCHAR(100)'')
a successful query would return value "NativeHawaiianOrOtherPacificIslander White". I am getting just the first value "NativeHawaiianOrOtherPacificIslander"
Just in terms of the xpath expression, and using the xml code in your question, this expression
*//HMDARaceType/text()
or this:
//*[local-name()='HMDARaceType']/text()
selects
NativeHawaiianOrOtherPacificIslander
White
Is that what you're looking for?

How to avoid finding ancestors with Protractor cssContainingText locator

I have a test that needs to determine if a span exists; I want to locate the span by the text it contains for scaleability. I tried to use element(by.cssContainingText('*', 'Test Text')) but it turns out that in addition to matching the span, it also matches every ancestor it has. How do I avoid this (.last will not work as there are multiple spans that contain the text and I want to locate the first one)?
Preferably, I want a locator that works exactly like buttonText except without the button restriction.
This will get the first element on the page that has the text that you provide:
element(by.xpath('//*[contains(text(), "test text")]'));
If you wanted to get all of the elements, just tack on a .all after element.

How do I get the nth element with a certain name in the entire XML document?

so will something like this work using Hpple Xpath
//a[4]
The fourth tag in a html tree?
Or do i need to do it programmatically by counting in a for() loop?
The XPath for the fourth <a> in an HTML document is:
(//a)[4]
Your example //a[4] will produce a set of all <a>s that are the fourth <a> in their respective parent, and that is not what you want here.
See also: https://stackoverflow.com/a/14209492/1945651

Perl's HTML::Element - dumping just the descendants as HTML

I'm having trouble trying to output the contents of a matched node that I'm parsing:
<div class="description">some text <br/>more text<br/></div>
I'm using HTML::TreeBuilder::XPath to find the node (there's only one div with this class):
my $description = $tree->findnodes('//div[#class="description"]')->[0];
It finds the node (returned as a HTML::Element I believe) but $description->as_HTML includes the element itself too - I just want everything contained inside the element as HTML:
some text <br/>more text<br/>
I can obviously regex strip it out, but that feels messy and I'm sure I'm just missing a function somewhere to do it?
Try doing this :
my $description = $tree->findnodes('//div[#class="description"]/text()')->[0];
This is a Xpath trick.
Use ./node() to fetch all subnodes including text and elements.
my $description = $tree->findnodes('//div[#class="description"]/node()');

Bricolage: how to check if a story has a particular field?

In the Bricolage CMS, what is the way to check whether a story has a particular field (in this case called 'teaser') set?
Do you mean in a template? If you want to know if a story has a field in a template, you can use either the get_field() or the get_value() method. Use get_field() if you just want to know if the field is present, as it returns a Bric::Biz::Element::Field object (I assume Mason templating here):
if (my $field = $element->get_field('teaser')) {
$m->print('<p>', $field->get_value, "</p>\n");
}
If you want to know if a field has a value, you use get_value():
if (my $val = $element->get_value('teaser')) {
$m->print("<p>$val</p>\n");
}
That method will return undef if there is no field object, and the value of the field object if it exists. Note that if the value is an empty string or 0, nothing will be printed there, either.
But it's important to note that Bricolage documents are organized in a tree structure of elements. The best way to create templates is one for each container element. The above example, might be in a top-level "story" element template, where $element will be the top-level element itself. But if your "teater" field is in a subelement, say "Metadata", you'll want to create a "metadata" element template with the above code, and call it from your story element template, like so:
$burner->display_element('metadata');
See Bric::Templates for an introduction to Bricolage templating and the API.
HTH,
David