首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Groovy:GPath读取节点属性为map的xml文件

Groovy:GPath读取节点属性为map的xml文件
EN

Stack Overflow用户
提问于 2010-10-06 22:24:45
回答 1查看 2.3K关注 0票数 1

我有以下xml文件:

代码语言:javascript
复制
<doc_xml>
<nodes>
  <node id='1' spec="{spec_a=0.9, spec_b=0.1}" />
  <node id='2' spec="{spec_a=0.1, spec_b=0.3}" />
  <node id='3' spec="{}" />
</nodes>
</doc_xml>

这段代码是使用Groovy MarkupBuilder创建的。

现在我想在一个groovy脚本中解析这个文件:

代码语言:javascript
复制
def xml = new XmlParser().parseText(getDocXmlAsString());

xml.nodes.node.each {
   Map spec = it.@spec; // here I got an exception org.codehaus.groovy.runtime.typehandling.GroovyCastException

}

但我一直收到这样的异常:

代码语言:javascript
复制
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '{spec_a=0.9, spec_b=0.1}' with class 'java.lang.String' to class 'java.util.Map'

我的问题是,如何解析作为映射的xml属性?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-10-06 22:33:39

我怀疑您发布的代码和xml不是您遇到问题的实际代码和xml……

但是,假设您打算在发布示例xml时关闭<node/>标记,我尝试了下面的Groovy代码:

代码语言:javascript
复制
def xmlStr = """<doc_xml>
<nodes>
  <node id='1' spec="{spec_a=0.9, spec_b=0.1}"/>
  <node id='2' spec="{spec_a=0.1, spec_b=0.3}"/>
  <node id='3' spec="{}"/>
</nodes>
</doc_xml>"""

def xml = new XmlParser().parseText( xmlStr )
def spec = [:]

xml.nodes.node.each {
  spec = it.@spec
  println spec
}

它可以工作,并打印出来:

代码语言:javascript
复制
{spec_a=0.9, spec_b=0.1}
{spec_a=0.1, spec_b=0.3}
{}

这些是字符串,而不是你想要的地图...

要将它们作为地图获取,您可以这样做:

代码语言:javascript
复制
xml.nodes.node.each {
  spec = Eval.me( it.@spec.tr( '{=}', '[:]' ) )
  println spec
}

您需要tr调用,将您为地图选择的格式转换为groovy可以处理的格式……

正如您所说的生成XML,我建议您将xml更改为:

代码语言:javascript
复制
<doc_xml>
<nodes>
  <node id='1' spec="[spec_a:0.9, spec_b:0.1]"/>
  <node id='2' spec="[spec_a:0.1, spec_b:0.3]"/>
  <node id='3' spec="[:]"/>
</nodes>
</doc_xml>

那么,您可以使用Json或其他定制格式跳过tr() step...or吗?

不确定将映射存储在属性中是不是一个好方法,forward...it对我来说有点脆弱:-/

编辑

我明白你的意思了,这是Groovy添加了一种奇怪的格式,当它添加一个属性作为MarkupBuilder时……

也许一种解决方案是这样做?

代码语言:javascript
复制
import groovy.xml.MarkupBuilder

// Imaginary data that we're going to generate our XML from:
def nodeData = [
  [ id:1, spec_a:0.9, spec_b:0.1 ],
  [ id:2, spec_a:0.1, spec_b:0.3 ],
  [ id:3 ]
]

def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.doc_xml() {
  nodes() {
    nodeData.each {
      node( it )
    }
  }
}

def xmlStr = writer.toString()

println "Write out the XML"
println xmlStr

def xmlParse = new XmlParser().parseText( xmlStr )
def spec = [:]

println "Write out the Attributes for each node"
xmlParse.nodes.node.each {
  spec = it.attributes()
  println spec
}

这将输出:

代码语言:javascript
复制
Write out the XML
<doc_xml>
  <nodes>
    <node id='1' spec_a='0.9' spec_b='0.1' />
    <node id='2' spec_a='0.1' spec_b='0.3' />
    <node id='3' />
  </nodes>
</doc_xml>
Write out the Attributes for each node
[id:1, spec_a:0.9, spec_b:0.1]
[id:2, spec_a:0.1, spec_b:0.3]
[id:3]

如您所见,每个映射条目都被添加为一个属性,并且可以使用XmlParser中每个Node类上的attributes()调用将这些属性提取出来

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3873506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档