groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bayareagreg <bayareag...@gmail.com>
Subject XML namespace-aware groovy expressions
Date Sat, 09 Dec 2017 06:30:41 GMT
Suppose one has to deal with the following XML 

	String xml = "<items xmlns=\"http://example.org\">\n" +
                "  <ns1:item xmlns:ns1=\"urn:ns1\">foo</ns1:item>\n" +
                "  <ns2:item xmlns:ns2=\"urn:ns2\">bar</ns2:item>\n" +
                "  <ns3:item xmlns:ns3=\"urn:ns3\">zot</ns3:item>\n" +
                "  <ns1:item xmlns:ns1=\"urn:ns1\">foo2</ns1:item>\n" +
                "  <ns2:item xmlns:ns2=\"urn:ns2\">bar2</ns2:item>\n" +
                "  <ns3:item xmlns:ns3=\"urn:ns3\">zot2</ns3:item>\n" +
                "  <ns1:item xmlns:ns1=\"urn:ns1\">foo3</ns1:item>\n" +
                "  <ns2:item xmlns:ns2=\"urn:ns2\">bar3</ns2:item>\n" +
                "  <ns3:item xmlns:ns3=\"urn:ns3\">zot3</ns3:item>\n" +
                "</items>";

Furthermore, suppose one wants to only return items in a specific namespace,
such as “urn:ns2”, I.e. only bar, bar2 and bar3 in the example above
If one were to use an expression “payload.item”, where payload is bound to
above XML, they will get ALL the items, i.e. not what they want. They really
need to use an expression that is XML namespace aware

I looked up how groovy does it http://groovy-lang.org/processing-xml.html
If I am reading it correctly, there are two ways:
1. Via user explicitly specifying the namespace in the expression, something
like xmlMarkup.'x:movies'('xmlns:x':'http://www.groovy-lang.org’)
2. Via explicit calls to GPathResult.declareNamespace before the expression
is evaluated by the groovy engine. 

For reasons I don't want to go into (2) is not workable for us. We really
need the namespace to be declared as part of the groovy expression text, not
via a programmatic call to declareNamespace(). 
So I tried the following :

       String expr = "payload.'ns2:item'('xmlns:ns2':'urn:ns2')";
        Binding binding = new Binding();
        XmlSlurper parser = new XmlSlurper();
        GPathResult payload = parser.parseText(xml);
        binding.setVariable("payload", payload);

	GroovyShell shell = new GroovyShell();
        Script script = shell.parse(expr);
        script.setBinding(binding);
        Object result = script.run();
  
It raises an exception 
    [java] Exception in thread "main" groovy.lang.MissingMethodException: No
signature of method: groovy.util.slurpersupport.NodeChild.ns2:item() is
applicable for argument types: (java.util.LinkedHashMap) values:
[[xmlns:ns2:urn:ns2]]
     [java]     at
org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:56)
     [java]     at
org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:51)
     [java]     at
org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
     [java]     at
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
     [java]     at
org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
     [java]     at Script1.run(Script1.groovy:1)
     [java]     at Main3.main(Main3.java:35)

Please help if you can.
Thank you in advance
Greg



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html

Mime
View raw message