私は次のコマンドを持っています:
find . -iname '*.xml' | xargs xmlstarlet sel -N z="http://abc.com/article/1.0/" \\
--var zgtag="SuperTag" -t -m "/z:profile-extension" -i "//z:tag='$zgtag'" \\
-n -f -o "," -v "count(//z:zgContextsAnonymTotal[z:tag='$zgtag'])" -o "," \\
-v "//z:zgContextsAnonymTotal/z:tag[.='$zgtag']/@z:timestamp" -o "," \\
-v "count(//z:zgContextsREGTotal[z:tag='$zgtag'])" -o "," \\
-v "//z:zgContextsREGTotal/z:tag[.='$zgtag']/@z:timestamp" -o "," \\
-v "count(//z:zgContextsPremiumTotal[z:tag='$zgtag'])" -o "," \\
-v "//z:zgContextsPremiumTotal/z:tag[.='$zgtag']/@z:timestamp" | grep -v ^$
命令バージョンに変数がないため($zgtag
表示結果を使用せずに同じ値を繰り返し)動作しません。何が問題なのでしょうか?
これまでに調査した内容は次のとおりです。
--var zgtag="'SuperTag'"
一重引用符がない場合は、xmlstarletコンパイルされたXSLTが次の変数宣言を生成するためです。<xsl:variable select="SuperTag" name="zgtag"/>
これは明らかに間違っています。一重引用符はありません!- xmlstarletコンパイルされたXSLTに変数が正しく挿入されていないことがわかります。たとえば、次のようになります。
<xsl:choose>
<xsl:when test="//z:tag=''">
その後、このバージョンを使用しました。--var zgtag="'SuperTag'" -m "/z:profile-extension" -i '//z:tag=$zgtag'
これで、正しくコンパイルされたxmlstarletのXSLTデバッグ出力を取得します。
<xsl:template match="/">
<xsl:variable select="'SuperTag'" name="zgtag"/>
<xsl:for-each select="/z:profile-extension">
<xsl:choose>
<xsl:when test="//z:tag=$zgtag">
ただし、出力はまだ空であり、変数のない同じスクリプト(SuperTag
スクリプトを複数回直接挿入)は正常に機能します。したがって、このvarスタイルコマンドに何か問題があるようです。
そのため、定義された変数を正しく挿入して使用する方法の助けを歓迎します。定義は問題ではなく、問題はxmlstarletコマンドで変数を使用することです。
答え1
式の単純化された部分(名前空間なしなど)を見てみましょう。
xmlstarlet sel --var zgtag="SuperTag" -t -m "/profile-extension" -i "//tag='$zgtag'"
zgtag
と呼ばれるXPath変数を宣言しました$zgtag
。しかし、//tag='$zgtag'
シェルが構文解析できるように、式を二重引用符の中に入れました。このプロセスでは、変数を評価し、変数が$zgtag
まだ設定されていないことを知っています。だからあなたはこれを得ます:
xmlstarlet sel --var zgtag="SuperTag" -t -m "/profile-extension" -i "//tag=''"
その後、コマンドを実行します。明らかに望むようには行われません。
いつものように、解決策は一重引用符を使用してシェルから式を保護することです。 (そしてXPathで予期しない内部一重引用符を使用するときは削除してください)
xmlstarlet sel --var zgtag='"SuperTag"' -t -m "/profile-extension" -i '//tag=$zgtag'
通常、シェルで解析する必要がない文字列は一重引用符を使用し、そうでない場合は二重引用符を使用します。バラよりシェルの「...」、「...」、$'...'、および$"..."引用符の違いは何ですか?
作業された例結果を確認するための有効な入力または期待される出力がないため、ユーザーのコマンドに対してアプリケーションをテストすることはできません。代わりに、私はこのように提案します。
cat >xml <<'EOF'
<?xml version="1.0"?>
<outer>
<inner x="a">Element A text</inner>
<inner x="b">Element B text</inner>
</outer>
EOF
xmlstarlet sel -t --var e='"b"' -v '//inner[@x=$e]' -n <xml
Element B text