是否有可能编写一个正则表达式(搜索替换),当在XML字符串上运行时,会将该XML字符串漂亮地缩进输出?
如果可以的话,正则表达式是什么呢 :)
是否有可能编写一个正则表达式(搜索替换),当在XML字符串上运行时,会将该XML字符串漂亮地缩进输出?
如果可以的话,正则表达式是什么呢 :)
如果您不使用正则表达式,这样做会简单得多。实际上,我甚至不确定是否可以使用正则表达式。
大多数语言都有XML库,使此任务非常简单。您使用的是哪种语言?
有没有可能编写一个正则表达式(搜索替换),当在XML字符串上运行时[...anything]
不行。
使用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);
坚持使用DOM。如其他答案中建议的那样,某些库已经提供了一个函数,可以为您缩进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();
}
这只能通过多个正则表达式实现,这些表达式将像状态机一样运行。
你所寻找的更适合于即兴解析器。