XML要素を所定の位置にソートする方法は?

XML要素を所定の位置にソートする方法は?

IntelliJ IDEA構成ファイルのバージョンを制御しようとしています。以下は小さなサンプルです。

<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
  <component name="ChangeListManager">
    <ignored path="tilde.iws" />
    <ignored path=".idea/workspace.xml" />
    <ignored path=".idea/dataSources.local.xml" />
    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
    <option name="TRACKING_ENABLED" value="true" />
    <option name="SHOW_DIALOG" value="false" />
    <option name="HIGHLIGHT_CONFLICTS" value="true" />
    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
    <option name="LAST_RESOLUTION" value="IGNORE" />
  </component>
  <component name="ToolWindowManager">
    <frame x="1201" y="380" width="958" height="1179" extended-state="0" />
    <editor active="false" />
    <layout>
      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
      <window_info id="Palette&#9;" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
    </layout>
  </component>
</project>

/project/component[@name='ToolWindowManager']/layout/window_infoIDEが設定を保存するたびに、いくつかの要素がランダムな順序で保存されるように見えます。同じタイプのすべての要素は、常に同じ順序で同じ属性を持つように見えます。要素の順序は、IDEの機能とは何の関係もないことを考慮すると、要素は要素名でソートされ、属性値でソートされます。そして属性とスペースはそのまま残ります。

に基づいてもう一つの答え私はすでに到着しました。これ:

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

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

    <template match="*">
        <copy>
            <apply-templates select="@*"/>
            <apply-templates>
                <sort select="name()"/>
                <sort select="@*[1]"/>
                <sort select="@*[2]"/>
                <sort select="@*[3]"/>
                <sort select="@*[4]"/>
                <sort select="@*[5]"/>
                <sort select="@*[6]"/>
            </apply-templates>
        </copy>
    </template>
</stylesheet>

ほぼすべてが来ましたが、いくつかの問題があります。

  • ソートされませんすべて属性値(@*効果なし)
  • 空の要素の末尾()の前のスペースを削除<foo />します<foo/>
  • EOFに改行文字を追加します(私の考えではバグではありませんが、結果ファイルを元のものとあまり似ていません)。

ベストアンサー1

xmllint正式なXMLソートの詳細とそれが説明するものと一致するかどうかはわかりませんが、ファイルをソース管理に保存する前に正式なXMLソートを使用することをお勧めします。これに対して一貫性を維持する場合、バージョン管理は非常にきれいで便利です。以下をスクリプトに変更するか、gitを使用している場合はgithookスクリプトを起動するように設定できます。

$ xmllint --c14n originalConfig.xml > sortedConfig.xml
$ mv sortedConfig.xml originalConfig.xml

LinuxまたはMacを使用している場合は、上記の内容が適しています。 Windowsを使用している場合は、cygwinのようなものをインストールする必要があるかもしれません。

おすすめ記事