繁体   English   中英

正则表达式缩进XML文件

[英]Regex to Indent an XML File

是否可以编写一个REGEX(搜索替换),当在XML字符串上运行时,输出的XML字符串会很好地缩进?

如果是这样的话REGEX :)

如果你不使用正则表达式,那么这样做会更简单。 事实上,我甚至不确定正则表达式是否可行。

大多数语言都有XML库,可以使这项任务变得非常简单。 你用的是什么语言?

是否可以编写一个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);

我不知道单独的正则表达式是否可以执行任意XML输入的漂亮打印格式。 您需要程序应用正则表达式来查找标记,找到匹配的结束标记(如果标记不是自我关闭的),依此类推。 使用正则表达式解决这个问题实际上是使用错误的工具来完成工作。 简单地打印XML的最简单方法是使用XML解析器,读取它,设置适当的序列化选项,然后将XML序列化。

为什么要使用正则表达式来解决这个问题?

使用正则表达式将是一场噩梦。 基于节点的层次结构跟踪缩进级别几乎是不可能的。 或许perl的5.10正则表达式引擎可能有所帮助,因为它现在可以重入。 但是,我们不要走这条路......除此之外,您还需要考虑CDATA部分,这些部分可以嵌入需要被缩进忽略的XML声明并保存完好。

坚持使用DOM。 正如在另一个答案中所建议的那样,一些库已经提供了一个将为您缩进DOM树的函数。 如果不构建一个将比创建和维护将执行相同任务的正则表达式简化得多。

这里描述的黑暗伏都教regexp效果很好。
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();
  }

这只能通过多个正则表达式来实现,这些正则表达式将像状态机一样运行。

您正在寻找的东西更适合于袖口解析器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM