Powershell Add XmlElement As the first child - powershell

This is a variation of the following question at:
PowerShell: How to add XmlElement to a non-root element
So I'll run with the data the OP used in that question. Given the following XML snippet:
<clubs>
</clubs>
or
<clubs />
What I'm trying to do is add the first element so that my resulting XML looks like:
<clubs>
<club name="barracas" rating="awesome" />
</clubs>
So far, I have tried: Append, InsertAfter (although I'm not 100% sure how that works)
$newNode = $xml.CreateElement("club")
$newNode.SetAttribute("name", "barracas");
$newnode.SetAttribute("rating", "awesome");
$xml.clubs.Append($newnode)
$xml.clubs.InsertAfter($newNode, $xml.clubs)

$xml.clubs is a string in this scenario and not an XmlNode. Try this instead:
$xml.FirstChild.AppendChild($newNode)
Of course, if the element is further down the tree, you'd probably be better off using the SelectSingleNode() method

Related

JBoss CLI: add a nested element within an element without name attribute (adding "key" element inside "jwt")

Generally speaking, I am trying to add a nested element inside another one, where the parent element does not contain a name attribute:
<parentElement name="fooName">
<foo property1="abc"/>
</parentElement>
should become:
<parentElement name="fooName">
<foo property1="abc">
<fooChild property2="bcd"/>
</foo>
</parent>
The problem with this is that I cannot find a way to properly build the path for the CLI command:
/sybsystem=xxx/parentElement=fooName/foo:add(fooChild={property2="bcd"})
gives me an error Node path format is wrong around 'foo' (index=37).
I assume this is because the foo element doesn't have an attribute name.
More specifically I am looking for a way to add key element inside the jwt element:
<token-realm name="jwt-realm" principal-claim="sub">
<jwt issuer="${JWT_ISSUER}" audience="${JWT_AUDIENCE}" public-key="${JWT_PUBLIC_KEY}"/>
</token-realm>
should become:
<token-realm name="jwt-realm" principal-claim="sub">
<jwt issuer="${JWT_ISSUER}" audience="${JWT_AUDIENCE}" public-key="${JWT_PUBLIC_KEY}">
<key kid="xxx" public-key="${JWT_PUBLIC_KEY}"/>
</jwt>
</token-realm>
The command I am trying to use:
/subsystem=elytron/token-realm=jwt-realm/jwt:add(key={kid="xxx",public-key="${JWT_PUBLIC_KEY}"})
and the error I get: Node path format is wrong around 'jwt' (index=41).
Thanks to my outstanding colleague (he hasn't got an account here, shame), the answer has been found.
To update the key's map the following command can be used:
/subsystem=elytron/token-realm=jwt-realm:write-attribute(name=jwt, ... ,key-map={"xxx","${JWT_PUBLIC_KEY}"}})
(... here the list of other standard attributes of the jwt element).

Unable to unit test an XSLT template rule that generates an element with nested elements

I have an XSLT template that transforms this:
<WGS__LAT>N20340000</WGS__LAT>
to this:
<latitude>
<deg>20</deg>
<min>34</min>
<sec>00</sec>
<hSec>00</hSec>
<northSouth>North</northSouth>
</latitude>
I wrote an XSpec scenario to test the XSLT template:
<x:scenario label="location/latitude: Check that the XSLT assigns latitude the split-up value of WGS__LAT">
<x:context>
<WGS__LAT>N20340000</WGS__LAT>
</x:context>
<x:expect label="Expect: deg=20, min=34, sec=00, hSec=00, northSouth=North">
<latitude>
<deg>20</deg>
<min>34</min>
<sec>00</sec>
<hSec>00</hSec>
<northSouth>North</northSouth>
</latitude>
</x:expect>
</x:scenario>
I am certain that my XSLT template works correctly, so why does the XSpec tool report FAILED? I thought it might have something to do with whitespace in <x:expect> so I removed all whitespace:
<x:expect label="Expect: deg=20, min=34, sec=00, hSec=00, northSouth=North">
<latitude><deg>20</deg><min>34</min><sec>00</sec><hSec>00</hSec><northSouth>North</northSouth></latitude>
</x:expect>
Unfortunately, I still get FAILED. What am I doing wrong?
Without having the full report, and especially what you actually get, it's difficult to answer. But :
in that case, a going starting point is to wrap your context in another tag, and to set in the xspec which part of the result should match. Something like :
<x:context>
<foo>
<WGS__LAT>N20340000</WGS__LAT>
</foo>
</x:context>
<x:expect label="..." test="/foo/*" as="element(latitude)">
<latitude>
<deg>20</deg>
<min>34</min>
<sec>00</sec>
<hSec>00</hSec>
<northSouth>North</northSouth>
</latitude>
</x:expect>
You may have a look at wiki for more precise use of expectations.
Then, actual result and expected result are compared with fn:deep-equals(...) method. And so, there is no output processing on result or on expect. Il you use an #href on x:context or on x:expect, then there is a space-normalization, but I'm not perfectly sure of that.
You may have a look at this issue on indentation problems ; it's a quite long and still open thread.

Parsing XML and retrieving attributes from (nested?) elements

I am trying to get specific data from an XML file, namely X, Y coordinates that are appear, to my beginners eyes, attributes of an element called "Point" in my file. I cannot get to that data with anything other than a sledgehammer approach and would gratefully accept some help.
I have used the following successfully:
for Shooter in root.iter('Shooter'):
print(Shooter.attrib)
But if I try the same with "Point" (or "Points") there is no output. I cannot even see "Point" when I use the following:
for child in root:
print(child.tag, child.attrib)
So: the sledgehammer
print([elem.attrib for elem in root.iter()])
Which gives me the attributes for every element. This file is a single collection of data and could contain hundreds of data points and so I would rather try to be a little more subtle and home in on exactly what I need.
My XML file
https://pastebin.com/abQT3t9k
UPDATE: Thanks for the answers so far. I tried the solution posted and ended up with 7000 lines of which wasn't quite what I was after. I should have explained in more detail. I also tried (as suggested)
def find_rec(node, element, result):
for item in node.findall(element):
result.append(item)
find_rec(item, element, result)
return result
print(find_rec(ET.parse(filepath_1), 'Shooter', [])) #Returns <Element 'Shooter' at 0x125b0f958>
print(find_rec(ET.parse(filepath_1), 'Point', [])) #Returns None
I admit I have never worked with XML files before, and I am new to Python (but enjoying it). I wanted to get the solution myself but I have spent days getting nowhere.
I perhaps should have just asked from the beginning how to extract the XY data for each ShotNbr (in this file there is just one) but I didn't want code written for me.
I've managed to get the XY from this file but my code will never work if there is more than one shot, or if I want to specifically look at, say, shot number 20.
How can I find shot number 2 (ShotNbr="2") and extract only its XY data points?
Assuming that you are using:
xml.etree.ElementTree,
You are only looking at the direct children of root.
You need to recurse into the tree to access elements lower in the hierarchical tree.
This seems to be the same problem as ElementTree - findall to recursively select all child elements
which has an excellent answer that I am not going to plagiarize.
Just apply it.
Alternatively,
import xml.etree.ElementTree as ET
root = ET.parse("file.xml")
print root.findall('.//Point')
Should work.
See: https://docs.python.org/2/library/xml.etree.elementtree.html#supported-xpath-syntax

Webdriver kicks the bucket on "find_element"

I am using the Ruby interpretation of Webdriver. Now the webpage I am looking at may or may not contain a certain element. If it doesn't I would like to look for another element. However, whenever Webdriver can't find an element it throws an exception.
My question is, can I check to see if the element even exists on the page without littering my code with begin/rescue blocks ?
Any help is greatly appreciated.
The short answer is no. To check if element exists, you have to rescue errors. find_element always throw NoSuchElementError if element was not found. You can for example take a look at implementation of #exists? method in Watir-WebDriver.
Still, you can use find_elements method which will return empty array if not elements were found.
elements = #browser.find_elements(id: 'doesnt-exist')
if elements.empty?
# go to the next element
else
# work with element
element = elements.first
element.click
end

Does NSXMLParser eat blank values?

I have some XML which looks like this:
<?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><array><data>
<value><array><data>
<value><dateTime.iso8601>20100508T14:49:56</dateTime.iso8601></value>
<value><string></string></value>
<value><string>comment</string></value>
<value><string></string></value>
<value><string>Milestone milestone1 deleted</string></value>
<value><int>1</int></value>
</data></array></value>
</data></array></value>
</param>
</params>
</methodRepsonse>
NSXMLParser seems to not be giving any data back for the blank values resulting in an array with 4 items in it instead of 6.
Is there anything I can do to NSXMLParser to make it return an empty string for the blank values so that I can maintain the order of the data when it is returned?
So after whipping up a quick sample with a delegate that just prints out what's happening during parsing I don't see anything at all wrong with what's being parsed.
I suspect however that you're relying on an incorrect expectation that between calls to didStartElement... and didEndElement... you should get a foundCharacters... call with an empty string? My question is based on the way you phrased the title of your question because there's no such thing as a "blank value." Either there is a value, or there isn't.
Imagine instead your XML contained <string/> instead of the exactly equivalent <string></string>. You still get start/end notifications.
You should be creating your NSMutableString (presumably the type that you're using for your <string> elements) in didStartElement... when <string> is found, appending to that string IF foundCharacters... is called (it can get called more than once with the value in chunks), and tossing it into your array when it's done on didEndElement....
If you really want to be more robust, you'll also be wanting detect an error condition if you find the start of a new element before your string ends, assuming that it is in fact an error for you.
Not quite sure I understand your problem here. NSXMLParser would at least report the beginning and end of the elements. Would that not be enough the get them in the right order?