Можно ли написать REGEX (замена поиска), который при запуске в строке XML будет выводить эту строку XML с красивым отступом?
Если да, то что такое REGEX :)
Можно ли написать REGEX (замена поиска), который при запуске в строке XML будет выводить эту строку XML с красивым отступом?
Если да, то что такое REGEX :)
Можно ли написать REGEX (замена поиска), который при запуске в строке XML [... что-нибудь]
No.
Используйте синтаксический анализатор XML, чтобы прочитать строку, а затем сериализатор XML, чтобы записать ее обратно в «красивом» режиме.
Каждый XML-процессор имеет свои собственные параметры, поэтому они зависят от платформы, но вот несколько многословный способ, который работает в реализациях, совместимых с DOM уровня 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);
Сделать это было бы намного проще, если бы вы не использовали регулярное выражение. На самом деле я даже не уверен, что это возможно с регулярным выражением.
Большинство языков имеют XML-библиотеки, которые очень упростили бы эту задачу. Какой язык вы используете?
Я не знаю, может ли регулярное выражение в отдельности сделать красивый формат произвольного ввода XML. Вам понадобится регулярное выражение, применяемое программой, чтобы найти тег, найти соответствующие закрывающие теги (если тег не закрывается самостоятельно) и так далее. Использование регулярных выражений для решения этой проблемы на самом деле означает использование неправильного инструмента для работы. Самый простой способ красиво распечатать XML — это использовать анализатор XML, прочитать его, установить соответствующие параметры сериализации, а затем снова сериализовать XML.
Почему вы хотите использовать регулярное выражение для решения этой проблемы?
Использование регулярного выражения для этого будет кошмаром. Отследить уровень отступа на основе иерархии узлов будет практически невозможно. Возможно, механизм регулярных выражений Perl 5.10 может помочь, поскольку теперь он реентерабельный. Но не будем идти по этому пути... Кроме того, вам нужно будет принять во внимание разделы CDATA, которые могут встраивать XML-декларации, которые необходимо игнорировать отступом и сохранять в неизменном виде.
Держитесь ДОМ. Как было предложено в другом ответе, некоторые библиотеки уже предоставляют функцию, которая сделает для вас отступ дерева DOM. Если его не построить, это будет намного проще, чем создание и поддержка регулярных выражений, которые будут выполнять ту же задачу.
Описанное здесь регулярное выражение темного вуду отлично работает.
http://www.perlmonks.org/?node_id=261292
Его основное преимущество по сравнению с XML::LibXMl и другими заключается в том, что он на порядок быстрее.
Это было бы достижимо только с несколькими регулярными выражениями, которые будут работать как конечный автомат.
То, что вы ищете, гораздо лучше подходит для синтаксического анализатора манжеты.
Из этой ссылки :
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();
}