3

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

如果是这样,那是什么正则表达式 :)

4

7 回答 7

5

如果您不使用正则表达式,这样做会简单得多。事实上,我什至不确定正则表达式是否可行。

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

于 2009-02-12T17:36:21.450 回答
5

是否可以编写在 XML 字符串上运行时的 REGEX(搜索替换)[...anything]

不。

Use an XML parser to read the string, then an XML serialiser to write it back out in ‘pretty’ mode.

Each XML processor has its own options so it depends on platform, but here is the somewhat long-winded way that works on DOM Level 3 LS-compliant implementations:

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);
于 2009-02-12T18:42:15.053 回答
3

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

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

于 2009-02-12T17:41:16.230 回答
3

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

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

于 2009-02-12T17:49:49.703 回答
2

The dark voodoo regexp as described here works great.
http://www.perlmonks.org/?node_id=261292
Its main advantage against using XML::LibXMl and others is that it's an order of magnitude faster.

于 2010-07-30T09:12:34.327 回答
1

这只能通过多个正则表达式来实现,它的执行类似于状态机。

您正在寻找的东西更适合现成的解析器。

于 2009-02-12T17:37:47.203 回答
1

From this link:

  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();
  }
于 2015-12-10T19:57:26.487 回答