私は次のxmlファイルを持っています:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout Android:enabled="false" Android:orientation="horizontal" Android:id="@id/action_container"
Android:background="@null" Android:paddingLeft="4.0dip" Android:layout_width="0.0dip"
Android:layout_height="48.0dip" Android:layout_weight="1.0"
style="@style/Widget.Compat.NotificationActionContainer"
xmlns:Android="http://schemas.Android.com/apk/res/Android">
<ImageView Android:enabled="false" Android:layout_gravity="start|center" Android:id="@id/action_image"
Android:layout_width="@dimen/notification_action_icon_size"
Android:layout_height="@dimen/notification_action_icon_size" Android:scaleType="centerInside"
Android:alpha="0.5"/>
<TextView Android:enabled="false" Android:textColor="#ffcccccc"
Android:ellipsize="end"
Android:layout_gravity="start|center"
Android:id="@id/action_text" Android:paddingLeft="4.0dip"
Android:clickable="false" Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:singleLine="true" Android:alpha="0.5"
style="@style/Widget.Compat.NotificationActionText"/>
</LinearLayout>
余分なスペースと改行を削除しようとしています。
これは私が必要とする結果です:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout Android:enabled="false" Android:orientation="horizontal" Android:id="@id/action_container" Android:background="@null" Android:paddingLeft="4.0dip" Android:layout_width="0.0dip" Android:layout_height="48.0dip" Android:layout_weight="1.0" style="@style/Widget.Compat.NotificationActionContainer" xmlns:Android="http://schemas.Android.com/apk/res/Android">
<ImageView Android:enabled="false" Android:layout_gravity="start|center" Android:id="@id/action_image" Android:layout_width="@dimen/notification_action_icon_size" Android:layout_height="@dimen/notification_action_icon_size" Android:scaleType="centerInside" Android:alpha="0.5"/>
<TextView Android:enabled="false" Android:textColor="#ffcccccc" Android:ellipsize="end" Android:layout_gravity="start|center" Android:id="@id/action_text" Android:paddingLeft="4.0dip" Android:clickable="false" Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:singleLine="true" Android:alpha="0.5" style="@style/Widget.Compat.NotificationActionText"/>
</LinearLayout>
このコマンドを使ってみました
sed -i '' 's/^[ \t]*//;s/[ \t]*$//' file.xml
一部のスペースは削除されましたが、改行は削除されませんでした。
最終的には、たとえばImageViewの幅(Android:layout_width)を、そのid(@ id/action_image)だけを知って5dipに変更できるようにしたいと思います。
iDでxml要素を取得し、他のパラメーターの値を変更できるようにしたい
xmlstarlet
とそのfo
コマンドの使用:
$ xmlstarlet fo file.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:enabled="false" Android:orientation="horizontal" Android:id="@id/action_container" Android:background="@null" Android:paddingLeft="4.0dip" Android:layout_width="0.0dip" Android:layout_height="48.0dip" Android:layout_weight="1.0" style="@style/Widget.Compat.NotificationActionContainer">
<ImageView Android:enabled="false" Android:layout_gravity="start|center" Android:id="@id/action_image" Android:layout_width="@dimen/notification_action_icon_size" Android:layout_height="@dimen/notification_action_icon_size" Android:scaleType="centerInside" Android:alpha="0.5"/>
<TextView Android:enabled="false" Android:textColor="#ffcccccc" Android:ellipsize="end" Android:layout_gravity="start|center" Android:id="@id/action_text" Android:paddingLeft="4.0dip" Android:clickable="false" Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:singleLine="true" Android:alpha="0.5" style="@style/Widget.Compat.NotificationActionText"/>
</LinearLayout>
インデントを完全に省略するには、xmlstarlet fo -n
を使用します。
Android:layout_width
属性がAndroid:id
であるImageView
ノードの@id/action_image
属性を変更するには、XMLドキュメントを再フォーマットする必要はありません。
$ xmlstarlet ed -u '//ImageView[@Android:id="@id/action_image"]/@Android:layout_width' -v "5dip" file.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:enabled="false" Android:orientation="horizontal" Android:id="@id/action_container" Android:background="@null" Android:paddingLeft="4.0dip" Android:layout_width="0.0dip" Android:layout_height="48.0dip" Android:layout_weight="1.0" style="@style/Widget.Compat.NotificationActionContainer">
<ImageView Android:enabled="false" Android:layout_gravity="start|center" Android:id="@id/action_image" Android:layout_width="5dip" Android:layout_height="@dimen/notification_action_icon_size" Android:scaleType="centerInside" Android:alpha="0.5"/>
<TextView Android:enabled="false" Android:textColor="#ffcccccc" Android:ellipsize="end" Android:layout_gravity="start|center" Android:id="@id/action_text" Android:paddingLeft="4.0dip" Android:clickable="false" Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:singleLine="true" Android:alpha="0.5" style="@style/Widget.Compat.NotificationActionText"/>
</LinearLayout>
ここでは、xmlstarlet
を使用して、目的のノードの正しい属性を編集します。属性はXPath式を使用して選択されます
//ImageView[@Android:id="@id/action_image"]/@Android:layout_width
XPath式の//ImageView
は、ドキュメント内のImageView
ノードanywhereを検索します。トップレベルのLinearLayout
ノードの子ノードのみに制限するには、代わりに/LinearLayout/ImageView
を使用します。
コマンドの-v "5dip"
は、属性に新しい値を与えます。
厳密に言えば、質問は言う
iDでxml要素を取得できるようにしたい[...]
つまり、ノードの名前を知らなくても。これを行うには、XPath式のImageView
を*
に変更するだけです。そうすれば、Android:id
が指定された文字列と一致するallノードを更新します。
関連:
この制限されたhtmlコードの簡単なハックの1つは、次のとおりです。
$ Perl -F'(?m:^<|>$)' -0777 -ane '
pop @F;
print $_, qw[< >][$|--] for map { s/\n\h+/ /gr } @F;
print "\n";
' input.html
出力:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout Android:enabled="false" Android:orientation="horizontal" Android:id="@id/action_container" Android:background="@null" Android:paddingLeft="4.0dip" Android:layout_width="0.0dip" Android:layout_height="48.0dip" Android:layout_weight="1.0" style="@style/Widget.Compat.NotificationActionContainer" xmlns:Android="http://schemas.Android.com/apk/res/Android">
<ImageView Android:enabled="false" Android:layout_gravity="start|center" Android:id="@id/action_image" Android:layout_width="@dimen/notification_action_icon_size" Android:layout_height="@dimen/notification_action_icon_size" Android:scaleType="centerInside" Android:alpha="0.5"/>
<TextView Android:enabled="false" Android:textColor="#ffcccccc" Android:ellipsize="end" Android:layout_gravity="start|center" Android:id="@id/action_text" Android:paddingLeft="4.0dip" Android:clickable="false" Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:singleLine="true" Android:alpha="0.5" style="@style/Widget.Compat.NotificationActionText"/>
</LinearLayout>
sed
エディターを使用して、同じことを実行することもできます。
$ sed -e '
/^<.*>$/b
/^</,/\/\{0,1\}>$/!b
H;/^</h;/\/\{0,1\}>$/!d;g
s/[[:blank:]]*\n[[:blank:]]*/ /g
' input.html
awk
を使用して区切り文字を変更し、2つ以上の空白を1つに切り捨てます。
$ awk -v RS="<" -v FS="\n" -v ORS="\n" -v OFS=" " '$0 {$1="<"$1; gsub(/ +/," ",$0); print}' input.xml
layout_width
から5dip
への変更を含むawk
ソリューション:
awk -v RS='> *\n *' -v ORS='>\n' '/id="@id\/action_image"/{gsub("layout_width=[^ ]*","layout_width=\"5dip\"")}NF=NF' file
この特定のケースでは機能しますが、一般に、これらの標準Linuxツールはxmlファイルの処理には適していません。
出力:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout Android:enabled="false" Android:orientation="horizontal" Android:id="@id/action_container" Android:background="@null" Android:paddingLeft="4.0dip" Android:layout_width="0.0dip" Android:layout_height="48.0dip" Android:layout_weight="1.0" style="@style/Widget.Compat.NotificationActionContainer" xmlns:Android="http://schemas.Android.com/apk/res/Android">
<ImageView Android:enabled="false" Android:layout_gravity="start|center" Android:id="@id/action_image" Android:layout_width="5dip" Android:layout_height="@dimen/notification_action_icon_size" Android:scaleType="centerInside" Android:alpha="0.5"/>
<TextView Android:enabled="false" Android:textColor="#ffcccccc" Android:ellipsize="end" Android:layout_gravity="start|center" Android:id="@id/action_text" Android:paddingLeft="4.0dip" Android:clickable="false" Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:singleLine="true" Android:alpha="0.5" style="@style/Widget.Compat.NotificationActionText"/>
</LinearLayout>