0

我从一个经常更新的 XML 文件中获取一些数据,我需要从 XML 文件中获取数据并将其解析为一个数组并以非常特定的方式对其进行排序。

XML 文件看起来像这样。(将显示更多数据,混乱但相似)

<?xml version="1.0" encoding="UTF-8"?>
<metadata>
 <groupId>groupName</groupId>
 <artifactId>artifactName</artifactId>
 <versioning>
  <versions>
   <version>abranchname001-A1</version>
   <version>abranchname001-A2</version>
   <version>abranchname001-A3.ca82a6dff817ec66f44342007202690a93763949</version>
   <version>abranchname001-A4</version>
   <version>abranchname001-A40</version>
   <version>abranchname001-A50.085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7</version>
   <version>abranchname001-A61</version>
   <version>abranchname001-A64</version>
   <version>abranchname001-A70.a11bef06a3f659402fe7563abf99ad00de2209e6</version>
   <version>bbranchname003-A200</version>
   <version>bbranchname003-A2</version>
   <version>bbranchname003-A20</version>
   <version>bbranchname003-A22</version>
   <version>cbranchname002-Alpha-A20</version>
   <version>cbranchname002-Alpha-A200</version>
   <version>cbranchname002-Alpha-A22.f3abe64fc121b75f3f0566c73f2f1a4e8fffd68e</version>
   <version>cbranchname002-Alpha-A23</version>
  </versions>
 </versioning>
</metadata>

我需要如下创建一个数组(按分支名称排序+在“-A”之后按数字排序,如果存在周期,则忽略周期之后的内容)

['abranchname001-A70.a11bef06a3f659402fe7563abf99ad00de2209e6',
'abranchname001-A64',
'abranchname001-A61',
'abranchname001-A50.085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7',
'abranchname001-A40',
'abranchname001-A4',
'abranchname001-A3.ca82a6dff817ec66f44342007202690a93763949',
'abranchname001-A2',
'abranchname001-A1',
'bbranchname003-A200',
'bbranchname003-A22',
'bbranchname003-A20',
'bbranchname003-A2',
'cbranchname002-Alpha-A200',
'cbranchname002-Alpha-A23',
'cbranchname002-Alpha-A22.f3abe64fc121b75f3f0566c73f2f1a4e8fffd68e',
'cbranchname002-Alpha-A20']

这就是我所拥有的,我在这个 groovy 脚本中缺少什么?

File xmlfile = new File("./data.xml")

def dataArray = new XmlSlurper().parse(xmlfile).versioning.versions.version.collect{ (it=~/\d+|\D+/).findAll() }.sort().reverse().collect{ it.join() }

assert dataArray == [""] //for testing output
//return dataArray  // actual code step
4

1 回答 1

0

以下代码:

def xml = new XmlSlurper().parse(new File("data.xml"))
def p   = /([^-]+)-\D*(\d+)/

def versions = xml.versioning.versions.version.collect { v ->
  v.text() 
}.sort { a, b -> 
  def am = (a =~ p)
  def bm = (b =~ p)
  am[0][1] <=> bm[0][1] ?: (bm[0][2] as int) <=> (am[0][2] as int)
}

versions.each { v -> 
  println v
}

在您的数据集上运行时,打印出:

~> groovy solution.groovy
abranchname001-A70.a11bef06a3f659402fe7563abf99ad00de2209e6
abranchname001-A64
abranchname001-A61
abranchname001-A50.085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
abranchname001-A40
abranchname001-A4
abranchname001-A3.ca82a6dff817ec66f44342007202690a93763949
abranchname001-A2
abranchname001-A1
bbranchname003-A200
bbranchname003-A22
bbranchname003-A20
bbranchname003-A2
cbranchname002-Alpha-A200
cbranchname002-Alpha-A23
cbranchname002-Alpha-A22.f3abe64fc121b75f3f0566c73f2f1a4e8fffd68e
cbranchname002-Alpha-A20

~>

笔记:

  • 更改了正则表达式以匹配两组,第一个是分支名称,第二个200是后缀 ( ) 中的数字 ( A200)
  • 将排序更改为主要对分支名称进行排序,然后对后缀中的数字进行反向排序
  • 两个arg 排序闭包需要一个 int 返回值。太空船操作员 <=>非常适合这一点。
  • elvis 运算符 使得?:如果分支名称相等(?:返回零之前的表达式),我们将继续比较后缀中的数字
  • 需要注意的是,使用上述方法,仍然使用字母顺序比较分支名称,因此如果分支名称是'A200','A22'和'A20',它们将被排序为[A20,A200,A22]而不是[A20、A22、A200]。
  • am 和 bm 是java.util.regex.Matcher的实例
  • am[0][1]抓取第一个匹配组(正则表达式中的第一对括号),am[0][2]抓取第二个匹配组
  • 如果模式不匹配(我们有意外的分支或后缀),则此代码可能无法按预期工作并引发异常。要解决此问题,您可以使用或类似方法检查匹配项if (!am),并通过返回 -1、0 或 1 来决定如何对这些情况进行排序。
于 2019-04-25T06:19:29.280 回答