Regex для отступа файла XML - PullRequest
       5

Regex для отступа файла XML

3 голосов
/ 12 февраля 2009

Можно ли написать REGEX (поиск замены), который при запуске на XML-строке будет правильно выводить эту XML-строку?

Если это так, то что такое REGEX:)

Ответы [ 7 ]

5 голосов
/ 12 февраля 2009

Можно ли написать REGEX (поиск замены), который при запуске на XML-строке [... что-нибудь]

номер

Используйте синтаксический анализатор XML для чтения строки, а затем сериализатор XML, чтобы записать ее обратно в "симпатичном" режиме.

Каждый процессор XML имеет свои собственные параметры, поэтому он зависит от платформы, но вот несколько затейливый способ, который работает на реализациях DOM Level 3, соответствующих LS:

input= implementation.createLSInput();
input.stringData= unprettyxml;
parser= implementation.createLSParser(implementation.MODE_SYNCHRONOUS, null);
document= parser.parse(input);
serializer= implementation.createLSSerializer();
serializer.domConfig.setParameter("format-pretty-print", true);
prettyxml= serializer.writeToString(document);
5 голосов
/ 12 февраля 2009

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

Большинство языков имеют библиотеки XML, которые сделали бы эту задачу очень простой. Какой язык вы используете?

3 голосов
/ 12 февраля 2009

Использование регулярных выражений для этого будет кошмаром. Отслеживание уровня отступа на основе иерархии узлов будет практически невозможно. Возможно, Perl 5.10 движок регулярных выражений может помочь, так как он теперь реентерабельный. Но давайте не будем идти по этому пути ... Кроме того, вам нужно будет принять во внимание разделы CDATA, которые могут включать декларации XML, которые должны игнорироваться отступом и сохраняться без изменений.

Палка с DOM. Как было предложено в другом ответе, некоторые библиотеки уже предоставляют функцию, которая будет делать отступ для дерева DOM. В противном случае это будет гораздо проще, чем создавать и поддерживать регулярные выражения, которые будут выполнять ту же задачу.

3 голосов
/ 12 февраля 2009

Я не знаю, может ли регулярное выражение в отдельности сделать формат произвольного ввода XML. Вам понадобится регулярное выражение, применяемое программой, чтобы найти тег, найти соответствующие закрывающие теги (если тег не является самозакрывающимся) и так далее. Использование регулярных выражений для решения этой проблемы на самом деле использует неправильный инструмент для работы. Самый простой из возможных способов печати XML - использовать синтаксический анализатор XML, прочитать его, установить соответствующие параметры сериализации и затем сериализовать XML обратно.

Почему вы хотите использовать регулярные выражения для решения этой проблемы?

2 голосов
/ 30 июля 2010

Темное регулярное выражение вуду, как описано здесь, прекрасно работает.
http://www.perlmonks.org/?node_id=261292
Его главное преимущество перед использованием XML :: LibXMl и других заключается в том, что он на порядок быстрее.

1 голос
/ 10 декабря 2015

С по этой ссылке :

  private static Regex indentingRegex=new Regex(@"\<\s*(?<tag>[\w\-]+)(\s+[\w\-]+\s*=\s*""[^""]*""|'[^']*')*\s*\>[^\<]*\<\s*/\s*\k<tag>\s*\>|\<[!\?]((?<=!)--((?!--\>).)*--\>|(""[^""]*""|'[^']'|[^>])*\>)|\<\s*(?<closing>/)?\s*[\w\-]+(\s+[\w\-]+\s*=\s*""[^""]*""|'[^']*')*\s*((/\s*)|(?<opening>))\>|[^\<]*", RegexOptions.ExplicitCapture|RegexOptions.Singleline);

  public static string IndentXml(string xml) {
        StringBuilder result=new StringBuilder(xml.Length*2);
        int indent=0;
        for (Match match=indentingRegex.Match(xml); match.Success; match=match.NextMatch()) {
              if (match.Groups["closing"].Success)
                    indent--;
              result.AppendFormat("{0}{1}\r\n", new String(' ', indent*2), match.Value);
              if (match.Groups["opening"].Success&&(!match.Groups["closing"].Success))
                    indent++;
        }
        return result.ToString();
  }
1 голос
/ 12 февраля 2009

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

То, что вы ищете, гораздо лучше подходит для парсера без манжеты.

...