In Groovy given a GPath I want to find that the path exists in XML document. So that I can set a value for the node. I can use xmlslurper for parsing the document. GPath is a string path represented in slashes format.
Look at example:
def xml = '''
<?xml version="1.0" encoding="UTF-8"?>
<data>
<level0 id="1" t="0">
<level1 id="lev1id01" att1="2015-05-12" val="12" status="0" year="2015" month="05" />
</level0>
</data>
'''
// find all nodes named 'level1'
def level1Nodes = new XmlSlurper().parseText(xml).level0.level1
// display found nodes names
level1Nodes.each { node ->
println "node: ${node.name()}"
}
// Get 'year' attribute value for 'level1' node
def level1YearValue = level1Nodes.each { node ->
println "${node.#year}"
}
Could you be more specific in your question?
Related
I'm trying to figure out how to add attributes to an array element
I get an error Error: Invalid character in name when trying to build the following XML from an object.
<?xml version="1.0" encoding="UTF-8"?>
<Requests xmlns="http://example.com">
<Request>
</Request>
<Request>
</Request>
</Requests>
Here is my object
let myObject = {
Requests:[
{$:{xmlns:"http://example.com"}},
{Request:{}},
{Request:{}}
]
}
let builder = new xml2js.Builder();
let xml = builder.buildObject(myObject);
console.log(xml)
I've also tried wrapping the name in quotes
{"$":{"xmlns":"http://example.com"}},
Stripping out the attribute declaration altogether produces the desired XML but obviously leaves out the needed attribute
<?xml version="1.0" encoding="UTF-8"?>
<Requests>
<Request>
</Request>
<Request>
</Request>
</Requests>
I suppose you should try this:
let myObject = {
Requests:{
$:{xmlns:"http://example.com"},
Request:[{}, {}]
}
I'm reading an xml file (Input.xml) using Unmarshall Jaxb using a my Pojo Object.
Reading Input File example with Unmarshaller.
File file = new File(".\\src\\test\\files\\Input.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(MerchantPayments.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
MerchantPayments MpObj = (MerchantPayments) jaxbUnmarshaller.unmarshal(file);
// Process MpObj..
What i need to do now, is to generate an Output.xml file containing the same data of the Input.xml file, but adding a new tag called <result> indicating if the record has been succesfully loaded.
Which is the best way to generate the output.xml file using Jaxb Marshal functionality containing the same data of the input.xml and adding a new tag?
I need to generate a new Pojo of the output.xml file in order to add the new tag or there are others way using Jaxb Marshaller?
Below the Input.xml file and the output.xml file that I need to geneate with the additional tag <result>
Input.xml
<?xml version='1.0' encoding='UTF-8'?>
<payments>
<payment>
<account>123</account>
<order>110000000001</order>
<amount>19.0</amount>
</payment>
<payment>
<account>1234</account>
<order>110000000002</order>
<amount>20.0</amount>
</payment>
</payments>
Output.xml, containing the new tag <result> :
<?xml version='1.0' encoding='UTF-8'?>
<payments>
<payment>
<account>123</account>
<order>110000000001</order>
<amount>19.0</amount>
**<result>Record loaded correctly</result>**
</payment>
<payment>
<account>1234</account>
<order>110000000002</order>
<amount>20.0</amount>
**<result>Record Failed</result>**
</payment>
</payments>
Thanks in advance.
To add new tag in Output.xml, first, you have to add following property corresponding setter/getter method in MerchantPayments class.
#XmlElement(name = "result")
private String result;
After unmarshalling, you'll get MpObj where you have to set "Record Failed" text to result field. Now, you can marshalling MpObj and will get desired output in Output.xml.
I have an xml that looks like this
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Samples>
<Sample>
<Name>
Sample1
</Name>
<Date>
01/20/2016
</Date>
</Sample>
</Samples>
I want to simply change the tag name from "Samples" to "SampleList". How will I do it?
replaceNode can be used to rename the node as below:
def xml = '''<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Samples>
<Sample>
<Name>
Sample1
</Name>
<Date>
01/20/2016
</Date>
</Sample>
</Samples>
'''
def result = new XmlSlurper().parseText(xml)
result.replaceNode {
'SampleList' it.children()
}
groovy.xml.XmlUtil.serialize(result)
replaceNode takes a closure as method parameter which delegates to a builder. Specifically in this case the node is replaced instead of appending it to main document. 'SampleList' it.children() is similar to 'SampleList(it.children())'.
Parsed xml's root element being Samples (which needs replacement), replaceNode was directly done on the result.
I have mule flow which stores the xml in session variable. I want this xml to be inserted in the xml which is generated in groovy.
My session variable looks like #[sessionVars.shippingdetails]
This session variable has <a><Subject1>science</Subject1><Subject2>Maths</Subject2></a>
When i use session variable in my xmlmarkup builder as like below. I am getting error as groovy.lang.GroovyRuntimeException: Namespace prefix: CDATA is not bound to a URI (javax.script.ScriptException). Message payload is of type: CaseInsensitiveHashMap (org.mule.api.transformer.TransformerMessagingException). Message payload is of type: CaseInsensitiveHashMap
import groovy.xml.XmlUtil
def builder = new groovy.xml.StreamingMarkupBuilder()
builder.encoding = "UTF-8"
// MAPPING
def person = {
// use mkp object which provides features like setting the namespace
mkp.xmlDeclaration()
mkp.declareNamespace("":"urn:abc:alos:BaseComponents")
//start with the XML root node closure
ItemRequest {
Requester{
subject(message.payload.subject)
}
Item{
Title(message.payload.name)
Description(message.payload.desc)
Category {
CategoryID(message.payload.cat_id)
}
ConditionID (message.payload.condition)
Mark (message.payload.Mark)
ShippingDetails [CDATA[sessionVars.shippingdetails]]
}
}
}
// WRITING
def writer = new StringWriter()
writer << builder.bind(person)
println writer.toString()
XmlUtil.serialize(builder.bind(person))
Hence my output xml should like below.
<?xml version="1.0" encoding="UTF-8"?>
<ItemRequest xmlns="urn:abc:alos:BaseComponents">
<Requester>
<subject>something</subject>
</Requester>
<Item>
<Title>Cooler Can Blue</Title>
<Description>This is the place for description.</Description>
<Category>
<CategoryID>562</CategoryID>
</Category>
<ConditionID>25</ConditionID>
<Mark>3</Mark>
<ShippingDetails>
<a>
<Subject1>science</Subject1>
<Subject2>Maths</Subject2>
</a>
</ShippingDetails>
</Item>
</ItemRequest>
Using Groovy 2.4.3, here is one way to get the output specified. (This does not address Mule):
import groovy.xml.*
def markupBuilder = new StreamingMarkupBuilder()
def xml = markupBuilder.bind { builder ->
mkp.declareNamespace( "": "urn:abc:alos:BaseComponents" )
ItemRequest {
Requester {
subject("something")
}
Item {
Title("Cooler Can Blue")
Description("This is the place for description.")
Category {
CategoryID("562")
}
ConditionID("25")
Mark("3")
ShippingDetails {
a {
Subject1("science")
Subject2("Maths")
}
}
}
}
}
def goal = """<?xml version="1.0" encoding="UTF-8"?><ItemRequest xmlns="urn:abc:alos:BaseComponents">
<Requester>
<subject>something</subject>
</Requester>
<Item>
<Title>Cooler Can Blue</Title>
<Description>This is the place for description.</Description>
<Category>
<CategoryID>562</CategoryID>
</Category>
<ConditionID>25</ConditionID>
<Mark>3</Mark>
<ShippingDetails>
<a>
<Subject1>science</Subject1>
<Subject2>Maths</Subject2>
</a>
</ShippingDetails>
</Item>
</ItemRequest>
"""
assert goal == XmlUtil.serialize(xml)
I am trying to fetch the namespace for an xml(xsd) file through Groovy.
The Node returned by the XmlParsers, and the GPathResult by XmlSlurper seems to ignore the namespace definitions.
As an example:
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
trying to fetch the attributes of the rootNode through
rootNode.attributes()
will retrieve only:
targetNamespace:http://www.w3schools.com
elementFormDefault:qualified
and leave out the xml:ns and xmlns definitions. Same result is contained in the # attribute of GPathResult.
Seems this has nothing to do with the Node class implementation and relies on the XmlParsers used.
So how should the XmlParser be implemented to include these attributes in the node, and any reason this has been left outside of Groovy?
Use a different variant of XmlSlurper constructor:
def xml = """<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com" xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
</xs:schema>
"""
assert new XmlSlurper(false, false, false).parseText(xml).attributes() == [
'xmlns:xs':'http://www.w3.org/2001/XMLSchema',
'targetNamespace':'http://www.w3schools.com',
'xmlns':'http://www.w3schools.com',
'elementFormDefault':'qualified'
]