XML使用相同的元素标记进行解析,但使用唯一数据

时间:2013-05-14 21:04:05

标签: xml parsing grails groovy xmlslurper

我正在解析具有许多相同标记的xml。在标记内部有一个值的名称,然后是值。我的问题是我需要将这些值分开。

这是我必须解析的xml的一个例子

  <Event>
  <ipaddress>
  10.0.0.0.
  </ip>

  <sourcesystem>
  somwhere
  </sourcesystem>
  <username>
   fred91
  </username>
   <user>
   <username>
  fred91
   </username>
   <account>
  fredsaccount
   </account>
   <id>
    f2234232
    </id>
   </user>
  ////BELOW IS THE PORTION OF THE XML THAT I AM HAVING ISSUES WITH NOTICE MULTPLE OF THE SAME ELEMENT TAG BUT THE name and values are unique/////
 <event-details>
   <name>Prairie Farms</name>
   <value>Summer Lane Happy Land USA</value>
 </event-details>  
 <event-details>
   <name>House on fire</name>
   <value>ashes</value>
 </event-details>
</Event>

请注意事件的名称会发生​​变化且不相关。如果它们相关则会更容易解析。名称是事件的名称,是唯一的。该值链接到该唯一名称。我的问题是试图弄清楚如何从通用元素标记中解析出唯一名称,然后为该名称指定相应的值。我被告知尝试使用一个集合,但我不知道如何去做。现在我把它解析出来就像这样。

sql.query(myQuery, []) { ResultSet rs ->
            while (rs.next()) { 

                  def parsing = new XmlSlurper().parseText(auditDetails)

                        def audit = new Audit()

                        audit.ipAddress = parsing."ip-address".text()
                        audit.sourceSystem = parsing."source-system".text()
                        audit.username = parsing."username".text()



                        parsing."user".each{
                            audit.username = parsing."user"."username".text()
                            audit.account = parsing."user"."account".text()
                            audit.id= parsing."user"."id".text()
                        }


                            /*if (parsing."event-details"."name".text().equals("createdTime")){
                                audit.name = parsing."event-details"."name".text
                                audit.createdTime = parsing."event-details"."value".text()
                            }*/
                            audit.name = parsing."event-details".name?.text()
                            audit.value = parsing."event-details".value?.text()
                        audit.eventDetails = parsing."event-details".text()

审核是我的对象,解析是我的xmlslurper。 现在,这只是将所有“名称”元素放入一个字符串中,并且在另一个字符串中都有相应的(按顺序分别)值。 像这样:

名称:Prairie FarmHouse着火

价值:Summer Lane Happy Land USAashes

我最终需要它像

Prairie Farms:Summer Lane Happy Land USA

House On Fire:灰烬

到目前为止,我知道了大约10个不同的唯一名称(通过查看这些查询与它们串在一起的内容来找到)

我需要写什么来获取它,以便它挑选出唯一的事件名称并将其与其值相关联。

parsing.'event-details'.each{
   if (parsing."event-details"."name".text().equals("createdTime")){
    audit.name = parsing."event-details"."name".text
    audit.createdTime = parsing."event-details"."value".text()
   }
}

^这是我的第一个想法,与所有已知的唯一名称一起进行,并通过这种方式为某个值指定名称。这只会将createdTime与值相关联,而忽略其余作为测试,但它甚至没有那么远。

有任何建议或意见吗?

很抱歉,如果这令人困惑。我觉得很难解释

谢谢你的时间!

2 个答案:

答案 0 :(得分:1)

唯一键可以帮助您使用map,如下所示:

def audit = [:]
parsing.'event-details'.each{
      def name = parsing.event-details.name?.text() 
      def value = parsing.event-details.value?.text()

      //To make it easy to understand
      audit << [name: value]

      //I would have used
      audit << [(parsing.event-details.name?.text()): parsing.event-details.value?.text()]
}

答案 1 :(得分:1)

假设您使用的是XmlSlurper,请尝试:

def audit = parsing.'event-details'.iterator().collectEntries {
  [ it.name, it.value ]
}

编辑:

好的,给出xml:

def x = '''<Event>
          |  <ipaddress>10.0.0.0</ipaddress>
          |  <sourcesystem>somwhere</sourcesystem>
          |  <username>fred91</username>
          |  <user>
          |    <username>fred91</username>
          |    <account>fredsaccount</account>
          |    <id>f2234232</id>
          |  </user>
          |  <event-details>
          |    <name>Prairie Farms</name>
          |    <value>Summer Lane Happy Land USA</value>
          |  </event-details>  
          |  <event-details>
          |    <name>House on fire</name>
          |    <value>ashes</value>
          |  </event-details>
          |</Event>'''.stripMargin()

审计类:

@groovy.transform.ToString(includeNames=true)
class Audit {
  String ipAddress, sourceSystem, username, account, id
  Map eventDetails
}

你可以这样做:

def audit = new XmlSlurper().parseText( x ).with { xml ->
  new Audit( ipAddress    : xml.ipaddress,
             sourceSystem : xml.sourcesystem,
             username     : xml.username,
             account      : xml.user.account,
             id           : xml.user.id,
             eventDetails : xml.'event-details'.iterator().collectEntries { [ it.name, it.value ] } )
}

println audit

打印:

Audit(ipAddress:10.0.0.0, sourceSystem:somwhere, username:fred91, account:fredsaccount, id:f2234232, eventDetails:[Prairie Farms:Summer Lane Happy Land USA, House on fire:ashes])

注意:

如果您使用的是Groovy&lt; 1.8.7,然后改变

             eventDetails : xml.'event-details'.iterator().collectEntries { [ it.name, it.value ] } )

             eventDetails : xml.'event-details'.inject( [:] ) { m, e -> m << [ (e.name): e.value ] } )