Сортировка XML-данных в массив с помощью groovy - PullRequest
0 голосов
/ 25 апреля 2019

Я получаю некоторые данные из 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>

Мне нужно создать массив, как показано ниже (сортировка по branchnames + сортировка по номеру после "-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']

Это то, что у меня есть, что я упускаю в этом отличном сценарии?

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

1 Ответ

0 голосов
/ 25 апреля 2019

следующий код:

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)
  • изменил сортировку для сортировки в основном по имени ветки и вторичной обратной сортировки по номеру в постфиксе
  • закрытие с двумя аргументами ожидает возвращаемого значения типа int. оператор космического корабля <=> идеально подходит для этого.
  • оператор elvis ?: делает так, что если имена ветвей равны (выражение до ?: возвращает ноль), мы затем продолжаем сравнивать числа в постфиксе
  • следует отметить, что при использовании вышеизложенного имена ветвей по-прежнему сравниваются с использованием алфавитного упорядочения, поэтому, если бы имена ветвей были «A200», «A22» и «A20», они были бы отсортированы как [A20, A200, A22 ] а не [А20, А22, А200].
  • am и bm являются экземплярами java.util.regex.Matcher
  • am[0][1] захватывает первую подходящую группу (первую пару символов в регулярном выражении), am[0][2] захватывает вторую подходящую группу
  • если шаблон не совпадает (у нас неожиданный ответвление или постфикс), этот код, вероятно, не будет работать должным образом и будет выдавать исключения. Чтобы исправить это, вы можете проверить совпадения, используя if (!am) или аналогичный, и решить, как отсортировать эти случаи, возвращая -1, 0 или 1.
...