このXMLをソートする方法は?
- アルファベット順で最初:
module
beforeproperty
。 - 次に、属性名をアルファベット順に指定し
<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タグ)をソートします。module
property
次に、各配列に適用される再帰関数を使用して、属性値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文書と、式が適用されたjq
JSON文書は次のとおりです。
{
"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でそのブロックを選択し、目的のブロックのみを並べ替えるか、文書全体をスマートに並べ替えることができます。
自動化したい場合は良い解決策ではありませんが、ワンタイムでは良いです。