5

毎日編集する必要のある複数のXMLファイルがあります。これらのファイルを読み取るソースを制御することも、XMLの形式を制御することもできません。

問題は、各要素が各ブロック内に独自の連続番号を必要とすることです。各ブロック内に200以上の要素が存在する場合があります。既存の長いブロックの早い段階でコマンドを挿入する必要がある場合は、面倒でエラーが発生しやすい後続の各要素に手動で番号を付け直す必要があります。

また、名前と値のペアは、必要な連番とは関係ありません。以下の値「origcmd1」は「foobar98765」である可能性があります。それらは私の問題を説明するためだけの数です。

例:

これから始めて:

<block1>
    <cmd1 name="origcmd1"></cmd1>
    <cmd2 name="origcmd2">someCmdsTakeParams,param2</cmd2>
    <cmd3 name="origcmd3"></cmd3>
</block1>

<block3>                             <c>no guarantee blocks are sequential #</c>
    <cmd1 name="cmd1"></cmd1>
    <cmd2 name="cmd2"></cmd2>
    <cmd3 name="cmd3"></cmd3>
</block3>

早い段階でコマンドを追加する必要がある場合、たとえばorigcmd1とorigcmd2の間で次のようにします。

<block1>
    <cmd1 name="origcmd1"></cmd1>
    <cmd2 name="NEWcmd1"></cmd2>                    <c>cmd2 & cmd3 inserted</c>
    <cmd3 name="NEWcmd1"></cmd3>
    <cmd4 name="origcmd2">someCmdsTakeParams,param2</cmd4>
    <cmd5 name="origcmd3"></cmd5>
</block1>

<block3>                             <c>no guarantee blocks are sequential #</c>
    <cmd1 name="cmd1"></cmd1>
    <cmd2 name="cmd2"></cmd2>
    <cmd3 name="cmd3"></cmd3>
</block3>

ここで、cmd4とcmd5を確認し、手動で番号を付け直す必要があります。何百ものコマンドがある場合、これは非常にイライラします。

これまでの解決策には、最初の行から番号を付け直すマクロを作成して、常に正しく番号が1であると想定することが含まれています。次に、一連の削除/貼り付けとCtrl-aを使用して、後続の各行番号をインクリメントします。残念ながら、マクロを正しく機能させることはできませんでした。

また、vim.orgでvimプラグインを調べましたが、解決策として認識できるものは何も見つかりませんでした。

Vimは私にとっては初めてのことですが、私はそれを気に入っており、これは解決に適したタイプの問題のようです。私が見逃した速いテクニックやプラグインに関するアイデアはありがたいです。

4

2 に答える 2

4

以下は私のために働くようです:

function! FixBlock()
  let g:pos_end = search("<\/bloc")
  call search("<block", "be")
  let s:i = 0
  while getpos(".")[1] < g:pos_end
    call search("cmd", "e")
    let s:i = s:i + 1
    exe 's/^\(.*\)\(<cmd[^ ]*\) \(.*\)/\1cmd' . s:i . ' \3/'
    "exe 's/^\(.*\)\(cmd.*\) \(.*\)/\1cmd' . s:i . ' \3/'
    exe 's?\(.*\)\(</cmd.*\)>\(.*\)?\1</cmd' . s:i . '>\3'
    normal j0
  endwhile
endfunction

map ,fb :call FixBlock()

それが機能するためには、修正したいブロックの内側にいる必要があります。mormalモードで、fbと入力するだけで、作業が完了します。

于 2012-12-07T05:40:57.253 に答える
2

XMLのフォーマットがかなり固定されている場合は、実際に(やや複雑な)Vimマクロを使用してコンテンツを操作できますが、XMLフォーマットの微妙な変更(またはコメントアウトされたブロック)が大混乱を引き起こし、データを破損する可能性があることに注意してください。一般的なテキストエディタとしてのVimはXML構造を実際に理解していないため、マクロをより堅牢にすることは困難です。

XSLTのようなXMLプロセッサがこの仕事に適している場合があります。(私にとっては、Vimマクロを記録するよりもXSLTで変換を記述するのは難しいです!しかし、これが頻繁に必要な場合は、投資する価値があるかもしれません。)Vim内から呼び出すこともできます。:%!xsltproc ...

XSLT1.0スタイルシートの例...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*[starts-with(name(),'cmd')]">
        <xsl:element name="cmd{position()}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>
于 2012-12-07T07:51:07.997 に答える