web-dev-qa-db-ja.com

XMLファイルの動的コンテンツを置き換える

クイックサマリー:ノード内のテキストを毎週自動的に変更するBashスクリプトを作成する必要があります。スクリプトはノードと一致し、ノード内のテキストを置き換えます(これが可能な場合)?どうすればよいですか?

長い要約:ショップがあるMinecraftサーバーをホストします。各ショップには、/ ShowcaseStandalone/ffs-storage /ディレクトリに独自の.xmlファイルがあります。毎週日曜日にサーバーが再起動し、ターミナルでいくつかのコマンドを実行して、いくつかのことをリセットします。私が変えようとしていることの一つは、お店の一つです。ノード<itemstack>のテキストとノード<price>のテキストを変更したいと思います。別のフォルダにある.txtファイルからテキストを取得して、そのノードに挿入したいだけです。問題は、ノード内のテキストが毎週変更されることです。 bashを使用して2つのノード内の特定の行またはテキストを置き換える方法はありますか?

XMLファイル:

<?xml version="1.0" encoding="UTF-8"?>
<scs-shop usid="cac8480951254352116d5255e795006252d404d9" version="2" type="storage">
    <enchantments type="string"/>
    <owner type="string">Chadward27</owner>
    <world type="string">Frisnuk</world>
    <itemStack type="string">329:0</itemStack>
    <activity type="string">BUY</activity>
    <price type="double">55.0</price>
    <locX type="double">487.5</locX>
    <locY type="double">179.0</locY>
    <locZ type="double">-1084.5</locZ>
    <amount type="integer">0</amount>
    <maxAmount type="integer">0</maxAmount>
    <isUnlimited type="boolean">true</isUnlimited>
    <nbt-storage usid="23dffac5fb2ea7cfdcf0740159e881026fde4fa4" version="2" type="storage"/>
</scs-shop>

オペレーティングシステム: Linux Ubuntu 12.04

20
Clucky

xmlstarlet を使用して、次のようにXML内のShellファイルを編集できます。

xmlstarlet edit -L -u "/scs-shop/price[@type='double']" -v '99.66' file.xml

[〜#〜]注[〜#〜]

  • "/scs-shop/price[@type='double']"Xpath 式です
  • 見る xmlstarlet ed --help
18
Gilles Quenot

XMLの方法はすばらしいですが、通常のbashツールを使用する必要がある場合は、sedを使用して行を変更できます。例えば:

_PRICE=123
sed -i "s/\(<price.*>\)[^<>]*\(<\/price.*\)/\1$PRICE\2/" $XML_FILE_TO_MODIFY
_

これにより、価格が123に置き換えられます。

そのsedコマンドは気が遠くなるように思われるので、分解させてください。

\(<price.*>\)[^<>]*\(<\/price.*\)は一致するパターンです。 _\(_ ... _\)_はグループ化の括弧です。 _<price.*>_は始値に一致します。 _[^<>]*_は山かっこ以外のすべてに一致し、この場合は値札の内容に一致します。 _<\/price.*_は値札の終わりと一致します。スラッシュはsedの区切り文字なので、バックスラッシュでエスケープします。

_\1$PRICE\2_は、一致したテキストを置き換えるテキストです。 _\1_は、最初に一致した括弧グループを指します。これは、開始値札です。 _$PRICE_は、希望する価格が含まれる変数です。 _\2_は、2番目の括弧グループ(この場合は終了タグ)を指します。

12
Dan Bliss

Xmlstarletを持っているという贅沢はありませんでした。インライン置換を行うだけで解決策を見つけました。

template-parameter.xml

<ns:Parameter>
    <ns:Name required="true">##-ParamName-##</ns:Name>
    <ns:Value>
        <ns:Text>##-ParamValue-##</ns:Text>
    </ns:Value>
</ns:Parameter>

スニペット

tokenName="foo"
tokenValue="bar"    

#Replace placeholders in parameter template element
myParamElement=$(cat template-parameter.xml)
myParamElement=${myParamElement//##-ParamName-##/$tokenName}
myParamElement=${myParamElement//##-ParamValue-##/$tokenValue}  

結果

<ns:Parameter>
    <ns:Name required="true">foo</ns:Name>
    <ns:Value>
        <ns:Text>bar</ns:Text>
    </ns:Value>
</ns:Parameter>
2
Denno