簡體   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