In groovy Xpath function not working for a xml - groovy

I am having the below XML:
<orders>
<order xmlns:amz="http://www.amazon.co">
<amz:comp>amz</amz:comp>
</order>
<order xmlns:ebay="http://www.ebay.co">
<ebay:comp>ebay</ebay:comp>
</order>
</orders>
I checked the xpath expressions like //orders/order it is working but in groovy it is not working I'm not getting what is wrong.
Below is the code that I am using:
import groovy.xml.*;
def source = '''<orders>
<order xmlns:amz="http://www.amazon.co">
<amz:comp>amz</amz:comp>
</order>
<order xmlns:ebay="http://www.ebay.co">
<ebay:comp>ebay</ebay:comp>
</order>
</orders>'''
def root = new XmlSlurper().parseText(source).declareNamespace([
amz: "http://www.amazon.co",
ebay: "http://www.ebay.co"
])
println root.orders
println root.orders.order."amz:comp"
I am not getting any output for the above code.

In your example, root variable refers to the <orders> element, so when you call root.orders it is like you were looking for
<orders>
<orders>...</orders>
</orders>
Rename root variable to orders and do
println orders
println orders.order."amz:comp"
to get the following output:
amzebay
amz

Related

Python lxml.etree: how to add 'xml:lang="en-US"' as a namespace

I am trying to create a xml whose first element is:
<speak version="1.0"
xmlns="http://www.w3.org/2001/10/synthesis" xml:lang="en-US">
</speak>
I am able to add the first attributes with...
from lxml.etree import Element, SubElement, QName, tostring
root = Element('speak', version="1.0",
xmlns="http://www.w3.org/2001/10/synthesis")
...but not the namespace xml:lang="en-US". Based on several tuto/question like this and this I tried many solutions but none worked.
For example, I tried this :
class XMLNamespaces:
xml = 'http://www.w3.org/2001/10/synthesis'
root.attrib[QName(XMLNamespaces.xml, 'lang')] = "en-US"
But the ouput is
<speak xmlns:ns0="http://www.w3.org/2001/10/synthesis" version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" ns0:lang="en-US">
How can I create the xml:lang="en-US" of my first xml element?
The special xml: prefix is associated with the http://www.w3.org/XML/1998/namespace URI.
The following code adds xml:lang="en-US" to the root element:
root.attrib[QName("http://www.w3.org/XML/1998/namespace", "lang")] = "en-US"

How to access XML node containing a period using groovy.util.XmlParser

I am needing to read a XML file where certain node names contain periods here is an example:
<build>
<actions>
<hudson.model.ParametersAction>
<safeParameters class="sorted-set"/>
<parameters>
<hudson.model.StringParameterValue>
...
When I try to use the standard build.actions.hudson.model.ParametersAction.parameters I get
groovy.lang.MissingPropertyException: Exception evaluating property 'hudson' for java.util.concurrent.CopyOnWriteArrayList, Reason: groovy.lang.MissingPropertyException: No such property: hudson for class: hudson.model.ParametersAction
I also tried build.actions.'hudson.model.ParametersAction'.parameters with this error:
groovy.lang.MissingPropertyException: Exception evaluating property 'hudson.model.ParametersAction' for java.util.concurrent.CopyOnWriteArrayList, Reason: groovy.lang.MissingPropertyException: No such property: hudson.model.ParametersAction for class: hudson.model.ParametersAction
How can I access this property?
You are right that it's necessary to surround a "periodish" element with quotes. The below code works for me. If it still doesn't work for you, it will be better if you share the code snippet which instantiates XmlParser and parses the xml.
def xml = """
<build>
<actions>
<hudson.model.ParametersAction>
<safeParameters class="sorted-set"/>
<parameters>
<hudson.model.StringParameterValue>foo</hudson.model.StringParameterValue>
</parameters>
</hudson.model.ParametersAction>
</actions>
</build>
"""
def parser = new XmlParser()
def build = parser.parseText(xml)
println(build.actions.'hudson.model.ParametersAction'.parameters.'hudson.model.StringParameterValue'.text())
//prints foo as a result

Copy attribute values based on a preceding node attribute with Groovy

I'm trying to do something in SoapUi with Groovy and it's not working.
I have multiple nodes with many attributes and I need to extract the child node attribute based of a parent's attribute
For example:
<library id="82389389">
<book id="123" bookType="SF">
<price id="325" priceValue="5"/>
</book>
<book id="4741" bookType="History">
<price id="12388" priceValue="15"/>
</book>
<book id="2626" bookType="Drama">
<price id="12145" priceValue="40"/>
</book>
</library>
In this XML I need to extract priceValue based on the bookType and use it somewhere else (the order of the book nodes is changing)
I tried this but it doesn't work:
def response = .../library[1]
def i=0
def records = new XmlSlurper().parseText(response)
def size = records.book.size()
for (i=0,i<size,i++)
{
bookType1 = records.book[i].#bookType.first().value().text();
if (bookType1 == 'History')
{
def priceValueBook = records.book[i].price.#priceValue.first().value().text()
log.info priceValueBook
}
}
It's not clear exactly at what point you are trying to do this, but the following would work in SoapUI script step:
context.expand('${test_step#Response#//*:book[#bookType="History"]/*:price/#priceValue}')

Parsing an XML in Groovy through XML Slurper

I am having this strange problem of parsing an xml through XMLSlurper in groovy and it shows the size as 0. Cannot figure out why.
My xml file looks like:
<?xml version="1.0" encoding="iso-8859-1"?>
<sites>
<site name="OctUK">
<property name="warName">OctUKbuild-Deployable</property>
</site>
<site name="GbsJP">
<property name="warName">GbsJPbuild-Deployable</property>
</site>
</sites>
Code:
findSite("${project.GTA_BUILD_HOME}/platforms/pos/config/pos-sites.xml")
//Passed the path of the xml file to the method below:
GPathResult findSite(String sitesXml) {
xmlConfig = new XmlSlurper().parse(new File(sitesXml))
def siteGPath = xmlConfig.sites.site.findAll
// Check that a POS-sites.xml is valid
assert siteGPath.size() != 0, 'Error: no site found'
return(siteGPath)
}
The method fails with the error saying Error: no site found, because it is giving the result of siteGPath as 0. Not sure why it is giving the result as 0. It should have the size as 2.
Is there anything wrong I am doing. Any help is much appreciated. I am stuck at this point.
You don't need sites when looking at the xmlConfig object.
sites is the root node, so is implied, try:
assert xmlConfig.site.size() == 2
Also, xmlConfig.site is a instance of NodeChildren, but you seem to be declaring a return type of GPathResult
And I'm not sure what's missing from the end of your findAll call, as that should take a Closure, or empty parentheses

Where does xmlns:tns come from when using schemagen

We are using schemagen to create an XSD from some annotated POJOs.
Here is our ant target
<target name="generate-xsd" depends="compile">
<taskdef name="schemagen" classname="com.sun.tools.jxc.SchemaGenTask"
classpathref="xjc.classpath"/>
<schemagen srcdir="src" destdir="generated" includeantruntime="false">
<include name="com/acme/exam/delivery/records/**"/>
<schema namespace="http://www.acme.com/deliverylog"
file="deliverylog.xsd"/>
<schema namespace="" file="supplemental.xsd"/>
</schemagen>
</target>
This is generating
<xs:schema elementFormDefault="qualified" version="1.0"
targetNamespace="http://www.acme.com/deliverylog"
xmlns:tns="http://www.acme.com/deliverylog"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
Where does the tns namespace come from and what does it signify?
That infomration comes from the package level annotation #XmlSchema which can be found in the package-info class. See below for an example.
package-info
#XmlSchema(
namespace = "http://www.acme.com/deliverylo",
elementFormDefault = XmlNsForm.QUALIFIED)
package example;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
Sample XML
elementFormDefault specifies which elements should be namespace qualified (true = all, false = only global elements), and targetNamespace defines what the namespace is.
<foo xmlns="http://www.acme.com/deliverylog">
<bar>Hello World</bar>
</foo>
For More Information
http://blog.bdoughan.com/2010/08/jaxb-namespaces.html

Resources