1

ファイルを正しくPerlインデントするための次のスクリプトがあります。XML

@files = glob "*.xml";

undef $/;
for $file (@files) {
    $indent = 0;
    open FILE, $file or die "Couldn't open $file for reading: $!";
    $_ = readline *FILE;
    close FILE or die "Couldn't close $file: $!";

    # Remove whitespace between > and < if that is the only thing separating them
    s/(?<=>)\s+(?=<)//g;

    # Indent
    s{  # Capture a tag <$1$2$3>,
        # a potential closing slash $1
        # the contents $2
        # a potential closing slash $3
        <(/?)([^/>]+)(/?)> 

        # Optional white space
        \s*

        # Optional tag.
        # $4 contains either undef, "<" or "</"
        (?=(</?))?
    }
    {
        # Adjust the indentation level.
        # $3: A <foo/> tag. No alteration to indentation.
        # $1: A closing </foo> tag. Drop one indentation level
        # else: An opening <foo> tag. Increase one indentation level
        $indent +=
            $3 ?  0 :
            $1 ? -1 :
                  1;

        # Put the captured tag back into place
        "<$1$2$3>" .
        # Two closing tags in a row. Add a newline and indent the next line
    ($1 and defined($4) and ($4 eq "</") ? "\n" . ("  " x $indent) : 
$4                                   ? "\n" . ("  " x $indent) :
                                       ""
        )
    # /g repeat as necessary
    # /e Execute the block of perl code to create replacement text
    # /x Allow whitespace and comments in the regex
    }gex;

    open FILE, ">", $file or die "Couldn't open $file for writing: $!";
    print FILE or die "Couldn't write to $file: $!";
    close FILE or die "Couldn't close $file: $!";
}

まず、 mytabsをインデントしていて、 2 つの空白が必要でした。また、次の行ではなく、同じインデントで同じ行にあるように、同じインデントでタグを生成しています。

<?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE kit SYSTEM "tc.dtd"><kit><contact/><description>

あるべき場所:

  <?xml version="1.0" encoding="iso-8859-1"?>
  <!DOCTYPE kit SYSTEM "tc.dtd">
  <kit>
      <contact/>
      <description>

...

XMLなどのindent する Perl ツールがあることは認めますが、タグXML-Tidyが原因で、依存関係自体ではなく、同じファイルのインデント (書式設定) だけを気にしているのにtc.dtd、ファイルの解決できない依存関係について不平を言うエラーが常に発生します。tc.dtd私のPerl正規表現の何が問題になっていますか?

4

2 に答える 2

2

あなたは常に use strictそしてすべてのプログラムuse warningsのトップにいなければなりません。これは、コードのヘルプを求めている場合に特に当てはまります。これらの手段は、他の方法では見落とされる可能性のある単純なエラーをキャッチできるためです。

字句ファイルハンドルも使用してください。コメントが多すぎてコードを明確にできません

タグがすでにインデントされている深さを考慮していないため、コードはおそらく失敗しています。2つの連続するタグの前にスペースを追加するだけです。特に、これ" " x -1は機能せず、PCDATA(テキスト)コンテンツを含む要素は単に無視され、現在のインデントのままであることに注意してください。

XMLのフォーマットは、思ったほど簡単ではありません。皆さんのアドバイスを受けて、既存のモジュールを使用してデータをフォーマットする必要があります。両方ともXML::LibXMLフォーマットXML::Twigオプションがあります。はい、対応するDTDにアクセスする必要がありますが、それは良いことです

于 2012-08-27T14:14:14.343 に答える
2

必ずしも検証されないツールxmllintを使用できます。例:

入力 (不適切な形式):

<?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE kit SYSTEM "tc.dtd"> <kit>
  <contact/>      <description>chunky bacon</description> </kit>

実行するxmllint --format file.xmlと、次のようになります。

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE kit SYSTEM "tc.dtd">
<kit>
  <contact/>
  <description>chunky bacon</description>
</kit>
于 2012-08-27T13:40:15.223 に答える