属性別にXML要素をソートする方法は?

属性別にXML要素をソートする方法は?

このXMLをソートする方法は?

  1. アルファベット順で最初:modulebefore property
  2. 次に、属性名をアルファベット順に指定し<module name="ClassTypeParameterName"/>ます<module name="PackageName"/>
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN" "https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
  <property name="severity" value="error"/>
  <property name="fileExtensions" value="java"/>
  <module name="NewlineAtEndOfFile"/>
  <module name="FileTabCharacter"/>
  <module name="TreeWalker">
    <module name="PackageName"/>
    <module name="ClassTypeParameterName"/>
    <module name="InterfaceTypeParameterName"/>
    <module name="MethodTypeParameterName"/>
    <module name="LambdaParameterName"/>
    <module name="PatternVariableName"/>
    <module name="RecordComponentName"/>
    <module name="RecordTypeParameterName"/>
    <module name="TypeName">
      <property name="format" value="^[A-Z][_a-zA-Z0-9]*$"/>
    </module>
    <module name="AvoidDoubleBraceInitialization"/>
    <module name="AvoidNoArgumentSuperConstructorCall"/>
    <module name="OneTopLevelClass"/>
    <module name="OuterTypeFilename"/>
  </module>
</module>

xqここで使用されているものを使いたいです。UNIXでは、Bashスクリプトを使用してXMLファイルをソートしますか?

答え1

おそらく次のようなものが欲しいでしょう。

xq -x -S 'walk(if type == "array" then sort_by(."@name") else . end)' file

-S(または)を使用すると、キーがキーの前に来るように、名前に基づいて--sort-keysキー(XMLタグ)をソートします。moduleproperty

次に、各配列に適用される再帰関数を使用して、属性値walk()(で書かれている)に基づいてsort_by()各配列の要素をソートします。name."@name"

このwalk()使用法は、以下とほぼ同じです。jqマニュアルの例

これにより、次のような出力が生成されます。

<module name="Checker">
  <module name="FileTabCharacter"></module>
  <module name="NewlineAtEndOfFile"></module>
  <module name="TreeWalker">
    <module name="AvoidDoubleBraceInitialization"></module>
    <module name="AvoidNoArgumentSuperConstructorCall"></module>
    <module name="ClassTypeParameterName"></module>
    <module name="InterfaceTypeParameterName"></module>
    <module name="LambdaParameterName"></module>
    <module name="MethodTypeParameterName"></module>
    <module name="OneTopLevelClass"></module>
    <module name="OuterTypeFilename"></module>
    <module name="PackageName"></module>
    <module name="PatternVariableName"></module>
    <module name="RecordComponentName"></module>
    <module name="RecordTypeParameterName"></module>
    <module name="TypeName">
      <property name="format" value="^[A-Z][_a-zA-Z0-9]*$"></property>
    </module>
  </module>
  <property name="fileExtensions" value="java"></property>
  <property name="severity" value="error"></property>
</module>

xq空のノードに対しても閉じるマーカーが明示的に作成されることに注意してください。問題を解決するには(<tag attr="..."></tag>に変更<tag attr="..."/>)、結果をxmlstarlet foまたはに渡しますxmlstarlet format


ちなみに、元のXML文書からソートせずに変換されたJSON文書と、式が適用されたjqJSON文書は次のとおりです。

{
   "module": {
      "@name": "Checker",
      "module": [
         { "@name": "NewlineAtEndOfFile" },
         { "@name": "FileTabCharacter" },
         {
            "@name": "TreeWalker",
            "module": [
               { "@name": "PackageName" },
               { "@name": "ClassTypeParameterName" },
               { "@name": "InterfaceTypeParameterName" },
               { "@name": "MethodTypeParameterName" },
               { "@name": "LambdaParameterName" },
               { "@name": "PatternVariableName" },
               { "@name": "RecordComponentName" },
               { "@name": "RecordTypeParameterName" },
               {
                  "@name": "TypeName",
                  "property": { "@name": "format", "@value": "^[A-Z][_a-zA-Z0-9]*$"
               },
               { "@name": "AvoidDoubleBraceInitialization" },
               { "@name": "AvoidNoArgumentSuperConstructorCall" },
               { "@name": "OneTopLevelClass" },
               { "@name": "OuterTypeFilename" }
            ]
         }
      ],
      "property": [
         { "@name": "severity", "@value": "error" },
         { "@name": "fileExtensions", "@value": "java" }
      ]
   }
}

答え2

私はOPと非常によく似た問題に直面しました(オンラインツールを除く顧客データを含むxmlに問題が追加されました)、最初にxqこのスクリプトを開始点として使用してかなりの成功を収めました。https://unix.stackexchange.com/a/659245/367314

vscodeしかし、最後にコードブロックを並べ替えて深さを整理できる素晴らしいプラグインを見つけました。他の人に役立つかと思ってここに文を載せると思いました。

https://marketplace.visualstudio.com/items?itemName=1nVitr0.blocksort

ブロックソートプラグインのデモ

ファイル内の特定のブロックのみを並べ替える場合は、UIでそのブロックを選択し、目的のブロックのみを並べ替えるか、文書全体をスマートに並べ替えることができます。

自動化したい場合は良い解決策ではありませんが、ワンタイムでは良いです。

関連情報