I'm trying to parse and modify a Maven's pom.xml using Groovy's XmlSlurper. My pom.xml declares the namespace xsi.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
     http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>a-group-id</groupId>
<artifactId>an-artifact-id</artifactId>

My Groovy source is as follows:

import groovy.xml.XmlUtil
def pom = new XmlSlurper().parse('pom.xml')
   .declareNamespace('': 'http://maven.apache.org/POM/4.0.0',
      xsi: 'http://www.w3.org/2001/XMLSchema-instance')
//manipulate the pom
println XmlUtil.serialize(pom)

As you notice, I've declared the first namespace as empty. However in the output tag0 is added everywhere.

<?xml version="1.0" encoding="UTF-8"?>
<tag0:project xmlns:tag0="http://maven.apache.org/POM/4.0.0"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
      http://maven.apache.org/maven-v4_0_0.xsd">
<tag0:modelVersion>4.0.0</tag0:modelVersion>
<tag0:groupId>a-group-id</tag0:groupId>
<tag0:artifactId>an-artifact-id</tag0:artifactId>

How to avoid that?

For the moment my workaround is removing the tags manually:

println XmlUtil.serialize(pom).replaceAll('tag0:', '').replaceAll(':tag0', '')
有帮助吗?

解决方案

You can construct the XmlSlurper with no namespace awareness like so:

import groovy.xml.XmlUtil

def pom = new XmlSlurper( false, false ).parse( 'pom.xml' )
println XmlUtil.serialize(pom)

Which should give you the answer you want... No idea currently about how to maintain comments during the slurp/serialize cycle :-(

As you say, it might be possible with XmlParser, but my current attempts have failed :-( There's some code here which might get you close, but as yet I've had no success :-(

其他提示

I had the same issue with "tag0" getting added to elements that didn't define a namespace (i.e they were in the "no namespace" namespace). I fixed this by adding

declareNamespace('': '')

which resets elements from being in the default namespace to being in the "no namespace" namespace.

I found that it is better to use XmlParser rather than XmlSlurper if you are dealing with namespaces and having the tag0 problem. Syntactically they seem the same, eg:

def root = new XmlParser().parse(new File('example.xml'))
println XmlUtil.serialize(root)

The above code would output the example.xml exactly as it should be including namespaces.

If you want to process the root in some way, eg find a specific node, use the Groovy API and output the result, eg

def root = new XmlParser().parse(new File('example.xml')
def result = root."ns:Element"[0]
println XmlUtil.serialize(result)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top