Quantcast

Modify XML

classic Classic list List threaded Threaded
26 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Modify XML

citron
Hi,

I have been trying to figure out how to modify an XML file containing namespaces without success.

Could someone please provide a code example how to do this?

Thanks!!


Express yourself instantly with MSN Messenger! MSN Messenger
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Modify XML

tugwilson

citron wrote
Hi,

I have been trying to figure out how to modify an XML file containing namespaces without success.

Could someone please provide a code example how to do this?

what sort of modification are you trying to do?

John Wilson

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

citron
Hi John,
 
I have now managed to modify the xml but there is one problem left.
 
Every element are prefixed in the modified xml file, but the original file uses a default namespace.
 
How do I get rid of all the prefixes in the output?
 
I have tried the mkp.declareNamespace("":  "http://java.sun.com/xml/ns/j2ee") without success, as suggested here
http://www.nabble.com/XmlSlurper---StreamingMarkupBuilder---Namespaces-td7669152.html
 


> Date: Tue, 15 Jan 2008 02:25:09 -0800
> From: [hidden email]
> To: [hidden email]
> Subject: Re: [groovy-user] Modify XML
>
>
>
>
> citron wrote:
> >
> >
> > Hi,
> >
> > I have been trying to figure out how to modify an XML file containing
> > namespaces without success.
> >
> > Could someone please provide a code example how to do this?
> >
> >
>
>
> what sort of modification are you trying to do?
>
> John Wilson
>
>
> --
> View this message in context: http://www.nabble.com/Modify-XML-tp14813147p14836537.html
> Sent from the groovy - user mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
> http://xircles.codehaus.org/manage_email
>



Express yourself instantly with MSN Messenger! MSN Messenger
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

tugwilson

citron wrote
Hi John,
 
I have now managed to modify the xml but there is one problem left.
 
Every element are prefixed in the modified xml file, but the original file uses a default namespace.
 
How do I get rid of all the prefixes in the output?
 
I have tried the mkp.declareNamespace("":  "http://java.sun.com/xml/ns/j2ee") without success, as suggested here
http://www.nabble.com/XmlSlurper---StreamingMarkupBuilder---Namespaces-td7669152.html

Could you post a very small example?

it may be a bug:)

John Wilson
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

citron
I can also see that " is replaced with ' and the first line eg. <?xml version="1.0" encoding="UTF-8"?> is missing.
 
Anyway, here is an example:
 
<groovy>
 import groovy.xml.*;
 def application = new XmlSlurper().parse(new File('D:/INPUT.xml')).declareNamespace( "":
'http://www.tibco.com/xmlns/ApplicationManagement')
      
 for (binding in application.services.bw.bindings.binding)
 {
  [hidden email] = <A href='mailto:binding.@name.text()+"_DEV'>binding.@...()+"_DEV"
  binding.machine = binding.machine.text()+"_DEV"
 }      

 def builder = new StreamingMarkupBuilder()
 def copier = builder.bind{ mkp.yield(application) }
 def result = "$copier"
 def destination = new FileWriter('D:/OUTPUT.xml')
 copier.writeTo(destination)         
</groovy>
 
********** INPUT ***********************
<?xml version="1.0" encoding="UTF-8"?>
<application name="EAIAdapter" xmlns="http://www.tibco.com/xmlns/ApplicationManagement"> 
   <services>    
      <bw name="EAIAdapter.par">                    
         <bindings>              
            <binding name="CITRON">                  
               <machine>citron</machine>        
            </binding>          
         </bindings>      
      </bw>
   </services>
</application>
********** OUTPUT ***********************
<tag0:application name='EAIAdapter' xmlns:ns1='http://www.tibco.com/xmlns/ApplicationManagement'>
 <tag0:services>
  <tag0:bw name='EAIAdapter.par'>
   <tag0:bindings>
    <tag0:binding name='CITRON_DEV'>
     <tag0:machine>citron_DEV</tag0:machine>
    </tag0:binding>
   </tag0:bindings>
  </tag0:bw>
 </tag0:services>
</tag0:application>


> Date: Tue, 15 Jan 2008 06:52:10 -0800
> From: [hidden email]
> To: [hidden email]
> Subject: RE: [groovy-user] Modify XML
>
>
>
>
> citron wrote:
> >
> >
> > Hi John,
> >
> > I have now managed to modify the xml but there is one problem left.
> >
> > Every element are prefixed in the modified xml file, but the original file
> > uses a default namespace.
> >
> > How do I get rid of all the prefixes in the output?
> >
> > I have tried the mkp.declareNamespace("":
> > "http://java.sun.com/xml/ns/j2ee") without success, as suggested here
> > http://www.nabble.com/XmlSlurper---StreamingMarkupBuilder---Namespaces-td7669152.html
> >
>
>
> Could you post a very small example?
>
> it may be a bug:)
>
> John Wilson
> --
> View this message in context: http://www.nabble.com/Modify-XML-tp14813147p14841365.html
> Sent from the groovy - user mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
> http://xircles.codehaus.org/manage_email
>



Express yourself instantly with MSN Messenger! MSN Messenger
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

tugwilson
Thanks,

That's *so* much clearer.

I'll play around with your example and post something tomorrow morning (my timezone is GMT).

John Wilson

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

tugwilson
In reply to this post by citron

citron wrote
I can also see that " is replaced with ' and the first line eg. <?xml version="1.0" encoding="UTF-8"?> is missing.

Took less time than I expected:
import groovy.xml.StreamingMarkupBuilder
 
 doc = """<?xml version="1.0" encoding="UTF-8"?>
 <application name="EAIAdapter" xmlns="http://www.tibco.com/xmlns/ApplicationManagement"> 
    <services>   
       <bw name="EAIAdapter.par">                   
          <bindings>             
             <binding name="CITRON">                 
                <machine>citron</machine>       
             </binding>         
          </bindings>     
       </bw>
    </services>
 </application>"""

 def application = new XmlSlurper().parseText(doc)
     
application.services.bw.bindings.binding = {element->
                                      def attrs = element.attributes()
                                      attrs.name = "${attrs.name}_DEV"
                                      binding(attrs) {
                                        machine("${element.machine.text()}_DEV")
                                      }
 }

def builder = new StreamingMarkupBuilder()
System.out << builder.bind{
                                      mkp.xmlDeclaration()
                                       namespaces << ["": "http://www.tibco.com/xmlns/ApplicationManagement"]
                                        out << application
                                   }


Note the way we edit the document is to provide a closure which is called just before each binding element is to be emitted. The closure is given a GPathResult object which represents the binding element and its children. The closure is executed in builder mode and the result of executing the closure replaces the binding element in the document.

when we emit the document we explicitly emit the XML declaration and declare a default namespace.

No doubt you will have some more questions when you try it out yourself :)

John Wilson
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

tugwilson
This is a more general solution. It allows multiple elements in the <binding> element.

import groovy.xml.StreamingMarkupBuilder
 
 doc = """<?xml version="1.0" encoding="UTF-8"?>
 <application name="EAIAdapter" xmlns="http://www.tibco.com/xmlns/ApplicationManagement"> 
    <services>   
       <bw name="EAIAdapter.par">                   
          <bindings>             
             <binding name="CITRON">                 
                <machine>citron</machine>     
             </binding>         
          </bindings>     
       </bw>
    </services>
 </application>"""

 def application = new XmlSlurper().parseText(doc)
     
application.services.bw.bindings.binding = {element->
                                      def attrs = element.attributes()
                                      attrs.name = "${attrs.name}_DEV"
                                      binding(attrs) {
                                        element.children().each {
                                          if (it.name() == "machine" ) {
                                            machine("${element.machine.text()}_DEV")
                                          } else {
                                            out << it
                                          }
                                        }
                                      }
 }

def builder = new StreamingMarkupBuilder()
 System.out << builder.bind{
                                mkp.xmlDeclaration()
                                namespaces << ["": "http://www.tibco.com/xmlns/ApplicationManagement"]
                                out << application
                              }
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

citron
Thanks for your help John!
 
I have put the groovy code inside ant and its complainting about '<<'
Is it possible to modify the code to not use this syntax?
 
Thanks!


> Date: Wed, 16 Jan 2008 00:27:02 -0800
> From: [hidden email]
> To: [hidden email]
> Subject: RE: [groovy-user] Modify XML
>
>
> This is a more general solution. It allows multiple elements in the <binding>
> element.
>
> import groovy.xml.StreamingMarkupBuilder
>
> doc = """<?xml version="1.0" encoding="UTF-8"?>
> <application name="EAIAdapter"
> xmlns="http://www.tibco.com/xmlns/ApplicationManagement">
> <services>
> <bw name="EAIAdapter.par">
> <bindings>
> <binding name="CITRON">
> <machine>citron</machine>
> </binding>
> </bindings>
> </bw>
> </services>
> </application>"""
>
> def application = new XmlSlurper().parseText(doc)
>
> application.services.bw.bindings.binding = {element->
> def attrs = element.attributes()
> attrs.name = "${attrs.name}_DEV"
> binding(attrs) {
> element.children().each {
> if (it.name() == "machine" ) {
>
> machine("${element.machine.text()}_DEV")
> } else {
> out << it
> }
> }
> }
> }
>
> def builder = new StreamingMarkupBuilder()
> System.out << builder.bind{
> mkp.xmlDeclaration()
> namespaces << ["":
> "http://www.tibco.com/xmlns/ApplicationManagement"]
> out << application
> }
>
> --
> View this message in context: http://www.nabble.com/Modify-XML-tp14813147p14873660.html
> Sent from the groovy - user mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
> http://xircles.codehaus.org/manage_email
>



Express yourself instantly with MSN Messenger! MSN Messenger
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Modify XML

Nick Rothwell
> I have put the groovy code inside ant and its complainting about '<<'
> Is it possible to modify the code to not use this syntax?

Can you not just escape the Groovy code in a CDATA section?

... Ant XML ...

<![CDATA[
... Groovy code
]]>

... more Ant XML ...





Nick Rothwell / Cassiel.com Limited
www.cassiel.com


---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

citron
Good idea, but I can't make it work that way either..

> From: [hidden email]
> Date: Wed, 16 Jan 2008 16:19:36 +0000
> To: [hidden email]
> Subject: Re: [groovy-user] Modify XML
>
> > I have put the groovy code inside ant and its complainting about '<<'
> > Is it possible to modify the code to not use this syntax?
>
> Can you not just escape the Groovy code in a CDATA section?
>
> ... Ant XML ...
>
> <![CDATA[
> ... Groovy code
> ]]>
>
> ... more Ant XML ...
>
>
>
>
>
> Nick Rothwell / Cassiel.com Limited
> www.cassiel.com
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
> http://xircles.codehaus.org/manage_email
>


Express yourself instantly with MSN Messenger! MSN Messenger
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

tugwilson
The CDATA section is the obvious way of solving this - it's *very* odd that this does not work.

What error are you getting?

John Wilson

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Modify XML

Nick Rothwell

On 16 Jan 2008, at 17:56, tugwilson wrote:

> The CDATA section is the obvious way of solving this - it's *very*  
> odd that
> this does not work.

Alternatively (but less pleasantly), replacing "<<" with "&lt;&lt;"  
should also work.

        -- N.


Nick Rothwell / Cassiel.com Limited
www.cassiel.com


---------------------------------------------------------------------
To unsubscribe from this list please visit:

    http://xircles.codehaus.org/manage_email

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

citron
In reply to this post by tugwilson
the CDATA works indeed, my mistake.

I found that the error occurs if the input xml contains the character '\' twice in one same element.

So when I modified the contents in the input xml it worked.
from    <value>C:\temp\input</value>
to      <value>C:\temp/input</value>

Script Failed:
org.codehaus.groovy.control.MultipleCompilationErrorsException:
startup failed,
build.xml: 171: unexpected char: '\' @ line 171, column 25.



My next question is, how do I store the result in a sting instead of sending it to System.out ?





> Date: Wed, 16 Jan 2008 09:56:20 -0800
> From: [hidden email]
> To: [hidden email]
> Subject: RE: [groovy-user] Modify XML
>
>
> The CDATA section is the obvious way of solving this - it's *very* odd that
> this does not work.
>
> What error are you getting?
>
> John Wilson
>
>
> --
> View this message in context: http://www.nabble.com/Modify-XML-tp14813147p14887061.html
> Sent from the groovy - user mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
> http://xircles.codehaus.org/manage_email
>


Express yourself instantly with MSN Messenger! MSN Messenger
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

tugwilson

citron wrote
My next question is, how do I store the result in a sting instead of sending it to System.out ?
Write it to a StringWriter.

John Wilson
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

citron
when writing to a StringWriter,
this first prints the xml I want, but it appends the contents without xml tags to the xml string.
println writer.toString()

"<?xml version="1.0" encoding="US-ASCII"?>
<application name='EAIAdapter'...</bw></services></application>BusinessBusinessDomainOperationsCommonDetails/Connections/..."


Without a mkp.yield in the binding, the xml is not generatet properly
writer << mkp.yield(application)

"<?xml version="1.0" encoding="US-ASCII"?>
BusinessBusinessDomainOperationsCommonDetails/Connections/..."





> Date: Wed, 16 Jan 2008 13:53:26 -0800
> From: [hidden email]
> To: [hidden email]
> Subject: RE: [groovy-user] Modify XML
>
>
>
>
> citron wrote:
> >
> > My next question is, how do I store the result in a sting instead of
> > sending it to System.out ?
> >
>
> Write it to a StringWriter.
>
> John Wilson
>
> --
> View this message in context: http://www.nabble.com/Modify-XML-tp14813147p14896180.html
> Sent from the groovy - user mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
> http://xircles.codehaus.org/manage_email
>


Express yourself instantly with MSN Messenger! MSN Messenger
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

tugwilson

citron wrote
when writing to a StringWriter,
this first prints the xml I want, but it appends the contents without xml tags to the xml string.
println writer.toString()
This works here

import groovy.xml.StreamingMarkupBuilder
 
 doc = """<?xml version="1.0" encoding="UTF-8"?>
 <application name="EAIAdapter" xmlns="http://www.tibco.com/xmlns/ApplicationManagement"> 
    <services>   
       <bw name="EAIAdapter.par">                   
          <bindings>             
             <binding name="CITRON">                 
                <machine>citron</machine>     
             </binding>         
          </bindings>     
       </bw>
    </services>
 </application>"""

def application = new XmlSlurper().parseText(doc)
     
application.services.bw.bindings.binding = {element->
                                      def attrs = element.attributes()
                                      attrs.name = "${attrs.name}_DEV"
                                      binding(attrs) {
                                        element.children().each {
                                          if (it.name() == "machine" ) {
                                            machine("${element.machine.text()}_DEV")
                                          } else {
                                            out << it
                                          }
                                        }
                                      }
}

def w = new StringWriter()
 
def builder = new StreamingMarkupBuilder()
w << builder.bind{
                                mkp.xmlDeclaration()
                                namespaces << ["": "http://www.tibco.com/xmlns/ApplicationManagement"]
                                out << application
                              }

System.out << w


John Wilson
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

citron
When I try this, the xml encoding changes from UTF-8 to US-ASCII and the output xml is invalid, because the contents is appended as a long string.


> Date: Thu, 17 Jan 2008 00:55:07 -0800
> From: [hidden email]
> To: [hidden email]
> Subject: RE: [groovy-user] Modify XML
>
>
>
>
> citron wrote:
> >
> >
> > when writing to a StringWriter,
> > this first prints the xml I want, but it appends the contents without xml
> > tags to the xml string.
> > println writer.toString()
> >
>
> This works here
>
> import groovy.xml.StreamingMarkupBuilder
>
> doc = """<?xml version="1.0" encoding="UTF-8"?>
> <application name="EAIAdapter"
> xmlns="http://www.tibco.com/xmlns/ApplicationManagement">
> <services>
> <bw name="EAIAdapter.par">
> <bindings>
> <binding name="CITRON">
> <machine>citron</machine>
> </binding>
> </bindings>
> </bw>
> </services>
> </application>"""
>
> def application = new XmlSlurper().parseText(doc)
>
> application.services.bw.bindings.binding = {element->
> def attrs = element.attributes()
> attrs.name = "${attrs.name}_DEV"
> binding(attrs) {
> element.children().each {
> if (it.name() == "machine" ) {
>
> machine("${element.machine.text()}_DEV")
> } else {
> out << it
> }
> }
> }
> }
>
> def w = new StringWriter()
>
> def builder = new StreamingMarkupBuilder()
> w << builder.bind{
> mkp.xmlDeclaration()
> namespaces << ["":
> "http://www.tibco.com/xmlns/ApplicationManagement"]
> out << application
> }
>
> System.out << w
>
>
> John Wilson
> --
> View this message in context: http://www.nabble.com/Modify-XML-tp14813147p14914639.html
> Sent from the groovy - user mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
> http://xircles.codehaus.org/manage_email
>



Express yourself instantly with MSN Messenger! MSN Messenger
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

tugwilson

citron wrote
When I try this, the xml encoding changes from UTF-8 to US-ASCII and the output xml is invalid, because the contents is appended as a long string.
It uses US-ASCII because that's the safest guess when it can't tell the encoding used by the Writer.

You can force the encoding by

builder.encoding = "UTF-8"
builder.bind {...


By "contents is appended as a long string" do you mean that the XML is not pretty printed (i.e. it's all on one line)? That's OK, it's perfectly valid XML. The consumer will not care if there are line breaks or not.

If you want to view the XML with line breaks you can load it into an XML aware editor (most will pretty print format for you) or you can run ith through JTidy.

John Wilson
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Modify XML

citron
Perfect, the builder.encoding = "UTF-8" works fine, thanks!
 
Now the issues I have left are that the input xml cannot contain the character '\' twice in the same element, and that the output xml string is not valid.
 
It appears that the contents is added twice to the output xml. The first part is marked up nicely with xml, and second part without beeing marked up with xml.
 
I can throw away the second part with a substring,  but I prefere not to have to do this.
 
The output xml is valid when using System.out instead of sending it to a StringWriter.
 



> Date: Thu, 17 Jan 2008 01:54:59 -0800
> From: [hidden email]
> To: [hidden email]
> Subject: RE: [groovy-user] Modify XML
>
>
>
>
> citron wrote:
> >
> >
> > When I try this, the xml encoding changes from UTF-8 to US-ASCII and the
> > output xml is invalid, because the contents is appended as a long string.
> >
>
> It uses US-ASCII because that's the safest guess when it can't tell the
> encoding used by the Writer.
>
> You can force the encoding by
>
> builder.encoding = "UTF-8"
> builder.bind {...
>
>
> By "contents is appended as a long string" do you mean that the XML is not
> pretty printed (i.e. it's all on one line)? That's OK, it's perfectly valid
> XML. The consumer will not care if there are line breaks or not.
>
> If you want to view the XML with line breaks you can load it into an XML
> aware editor (most will pretty print format for you) or you can run ith
> through JTidy.
>
> John Wilson
> --
> View this message in context: http://www.nabble.com/Modify-XML-tp14813147p14915593.html
> Sent from the groovy - user mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe from this list please visit:
>
> http://xircles.codehaus.org/manage_email
>



Express yourself instantly with MSN Messenger! MSN Messenger
12
Loading...