Как преобразовать XML-форматированную строку в однострочную XML-строку без пробелов в grails/groovy?


Мне интересно, есть ли более простой способ преобразовать XML-форматированную строку с разрывами строк и вкладками в одну строку xml-строки без форматирования. в настоящее время я думаю о том, чтобы сделать

s.replaceAll("n",""); 
s.replaceAll("t","");
Но есть ли более лучший способ сделать это в grails/groovy?

Входной XML:

<chart subCaption="Mon, 24 Oct 2011-Tue, 21 Feb 2012" outCnvBaseFont="Arial" outCnvBaseFontSize="12" xAxisName="Day of the Month" yAxisName="Distinct User Count" formatNumberScale="0" decimalPrecision="0" showvalues="0" animation="1" numdivlines="3" numVdivlines="0" lineThickness="3" rotateNames="1">
  <categories>
    <category Label="Nov/28" showName="1" />
    <category Label="Nov/29" showName="0" />
    <category Label="Nov/30" showName="0" />
    <category Label="Dec/01" showName="0" />
    <category Label="Dec/02" showName="1" />
    <category Label="Dec/03" showName="0" />
    <category Label="Dec/04" showName="0" />
  </categories>
  <dataset seriesName="view/export" color="F5497D" showValue="1" alpha="100" anchorAlpha="0" lineThickness="2">
    <set value="0" />
    <set value="0" />
    <set value="0" />
    <set value="0" />
    <set value="0" />
    <set value="0" />
    <set value="0" />
  </dataset>
</chart>

Вывод xml

<chart subCaption="Mon, 24 Oct 2011-Tue, 21 Feb 2012" outCnvBaseFont="Arial" outCnvBaseFontSize="12" xAxisName="Day of the Month" yAxisName="Distinct User Count" formatNumberScale="0" decimalPrecision="0" showvalues="0" animation="1" numdivlines="3" numVdivlines="0" lineThickness="3" rotateNames="1"><categories><category Label="Nov/28" showName="1" /><category Label="Nov/29" showName="0" /><category Label="Nov/30" showName="0" /><category Label="Dec/01" showName="0" /><category Label="Dec/02" showName="1" /><category Label="Dec/03" showName="0" /><category Label="Dec/04" showName="0" /></categories><dataset seriesName="view/export" color="F5497D" showValue="1" alpha="100" anchorAlpha="0" lineThickness="2"><set value="0" /><set value="0" /><set value="0" /><set value="0" /><set value="0" /><set value="0" /><set value="0" /></dataset></chart>
3 3

3 ответа:

Этот скрипт также может быть полезен:

unpretty = pretty.replaceAll(/>(\n|\t|\s)*</, '><')
                 .replaceAll(/\n|\t/, ' ')
                 .replaceAll(/\s+/, ' ')

Удаляет лишние \n, \t, \s между угловыми скобками и преобразует лишние \n, \t, \s в один пробел внутри / снаружи тегов.

Если вы только хотите избавиться от \t и \n, то вы можете сделать что-то вроде этого:

s.collect { it != "\n" && it != "\t" ? it : "" }.join()
Это, конечно, предполагает, что нет семантически релевантных символов пробела в качестве значений атрибутов.

Это приведет к тому же эффекту, что и ваш пример, но он ничего не сделает для удаления пробелов. Удаление пробелов намного сложнее, так как между именами атрибутов и тегами требуется по крайней мере один символ пробела, и вы не можете удалить их из значений.

I не думайте, что есть короткий или элегантный способ сделать это. Вам нужно будет работать с реальным синтаксическим анализатором XML. Что-то вроде XMLSlurper было бы хорошим началом.


Править

Другая возможность выглядит примерно так:

def root = new XmlParser().parseText(xml)
new XmlNodePrinter(preserveWhitespace:false).print(root.body[0])

Проблема с этим решением заключается в том, что строка красиво напечатана с новыми строками и отступами, но вы можете объединить первый пример со вторым, чтобы преобразовать красиво напечатанную строку.

Самое простое решение, которое я могу придумать, - это использовать регулярное выражение для замены всех пробелов между угловыми скобками, например:

def test = '''<chart subCaption="Mon, 24 Oct 2011-Tue, 21 Feb 2012" outCnvBaseFont="Arial" outCnvBaseFontSize="12" xAxisName="Day of the Month" yAxisName="Distinct User Count" formatNumberScale="0" decimalPrecision="0" showvalues="0" animation="1" numdivlines="3" numVdivlines="0" lineThickness="3" rotateNames="1">
  <categories>
    <category Label="Nov/28" showName="1" />
    <category Label="Nov/29" showName="0" />
    <category Label="Nov/30" showName="0" />
    <category Label="Dec/01" showName="0" />
    <category Label="Dec/02" showName="1" />
    <category Label="Dec/03" showName="0" />
    <category Label="Dec/04" showName="0" />
  </categories>
  <dataset seriesName="view/export" color="F5497D" showValue="1" alpha="100" anchorAlpha="0" lineThickness="2">
    <set value="0" />
    <set value="0" />
    <set value="0" />
    <set value="0" />
    <set value="0" />
    <set value="0" />
    <set value="0" />
  </dataset>
</chart>
'''

println test.replaceAll(/>\s+</, '><')

Это сработало в моем тесте. Кроме того, поскольку угловые скобки недопустимы внутри атрибутов, это не должно влиять на внутреннее содержимое.

Однако он не удаляет лишние пробелы между атрибутами.