そのため、bashシェルスクリプトを使用してXMLファイルを操作する必要があるタスクがあります。
手順は次のとおりです。
以下は、必須でない情報が削除されたXMLのサンプルです。
<fmreq:fileManagementRequestDetail xmlns:fmreq="http://foobar.com/filemanagement">
<fmreq:property>
<fmreq:name>form_category_cd</fmreq:name>
<fmreq:value>Memos</fmreq:value>
</fmreq:property>
<fmreq:property>
<fmreq:name>object_name</fmreq:name>
<fmreq:value>Correspondence</fmreq:value>
</fmreq:property>
</fmreq:fileManagementRequestDetail>
Object_nameの下のvalue要素から値を取得し、それを相互参照して、form_category_cd value要素の下の値を新しい値に置き換える必要があります。
したがって、object_name-> valueがCorrespondenceの場合、form_category_cd->値はYYZである必要があります。
これが問題です。私たちのオペレーショングループが手元のツールに制限しているため、私はサーバーで利用可能なツールのみを使用できます。 xmllintを更新するための戦いでしたが、その後却下されました。私は--xpathをサポートしていないバージョンを使用しています。また、入手可能なバージョンは名前空間をサポートしていないため、xmllintは廃止されました。
私はsedを試しましたが、すべてのテスターが正常に動作しているにもかかわらず、正規表現が好きではないようです。
正規表現:
(<fmreq\:name>object_name<\/fmreq\:name>)(?:\n\s*)(<fmreq\:value>)(.*)(<\/fmreq\:value>)
グループ#3を取得する必要がありますが、sedはそれを返しません。代わりに、XMLファイルの内容全体を返します。
sed -e 's/\(<fmreq\:name>object_name<\/fmreq\:name>\)\(?:\n\s*\)\(<fmreq\:value>\)\(.*\)\(<\/fmreq\:value>\)/\3/' < c3.xml
私はawk/gawkに精通していないので、私はそれらを理解するのに苦労していますが、これも解決策が見つかればオープンです。
彼は古いawkのファンなので、上司を幸せにするためにawk/gawkのソリューションを用意したいのですが、困ったときに手に入れられるものを取り上げます。
ここでもツールを使用する必要があり、新しくインストールすることはできません。
sed
コマンドにはいくつかの問題があると思います:
-n
オプションを使用しないため、デフォルトではsed
は入力のすべての行を出力に出力します(sed
コマンドによって変更される可能性があります)。
sed
は最後の引数をファイル名として認識するため、リダイレクト< c3.xml
は必要ありません。
sed
は、複数行にわたる一致にはあまり適していません。たとえば here を参照してください。
以下はあなたの例でうまくいくようです:
sed -n "/<fmreq:name>object_name<\/fmreq:name>/ {n;p}" c3.xml | sed "s/^\s*<fmreq:value>\(.*\)<\/fmreq:value>/\1/g"
または、sed
呼び出しを1つだけ使用します。
sed -n "/<fmreq:name>object_name<\/fmreq\:name>/ {n;s/^\s*<fmreq:value>\(.*\)<\/fmreq:value>/\1/g;p}" c3.xml
このコマンドの機能の内訳:
オプション-n
は、行の処理が完了した後にパターンスペースを印刷しないようにsed
に指示します。そのため、明示的にp
コマンドを使用する必要があります。
/regex/
は、sed
に一致する行でのみ後続のコマンドを実行するようにregex
に指示します。
sed
コマンドn
は、パターンスペースの内容を、関心のある値を含む次の入力行で置き換えます。
sed
コマンドs/regex/replacement/
は、パターンスペースで最初に一致したregex
をreplacement
に置き換えます。
sed
コマンドp
は行を出力します。
XMLStarlet の使用:
$ xml ed -u '//fmreq:property[fmreq:name="object_name"]/preceding-sibling::fmreq:property/fmreq:name' -v YYZ file.xml
<?xml version="1.0"?>
<fmreq:fileManagementRequestDetail xmlns:fmreq="http://foobar.com/filemanagement">
<fmreq:property>
<fmreq:name>YYC</fmreq:name>
<fmreq:value>Memos</fmreq:value>
</fmreq:property>
<fmreq:property>
<fmreq:name>object_name</fmreq:name>
<fmreq:value>Correspondence</fmreq:value>
</fmreq:property>
</fmreq:fileManagementRequestDetail>
XPathの最初の部分である//fmreq:property[fmreq:name="object_name"]
は<fmreq:name>object_name</fmreq:name>
ノードを見つけ、/preceding-sibling::fmreq:property/fmreq:name
ビットは前の<fmreq:name>
ノードの<fmreq:property>
ノードを見つけます。