3

「v」で終わるliquibase XML変更ログからノードを抽出するためにxmlstarletを使用しています。changeSetviewName

ただし、xmlstarlet はends-withXPATH 関数が存在しないと不平を言っています。

$ xmlstarlet sel -N x="http://www.liquibase.org/xml/ns/dbchangelog" -t -m \
"/x:databaseChangeLog/x:changeSet[x:createView[ends-with(@viewName, 'v')]]" \
-c . public.db.changelog.xml

xmlXPathCompOpEval: function ends-with not found
Unregistered function
Stack usage errror
xmlXPathCompiledEval: 3 objects left on the stack.
runtime error: element for-each
Failed to evaluate the 'select' expression.
None of the XPaths matched; to match a node in the default namespace
use '_' as the prefix (see section 5.1 in the manual).
For instance, use /_:node instead of /node

XML は次のようになります。

<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
  <changeSet id="1391529990457-3">
    <createView viewName="myviewnamev"><!-- view definition here --></createView>
  </changeSet>
  <changeSet id="1391529990457-4">
    <createView viewName="anotherviewname"><!-- view definition here --></createView>
  </changeSet>
</databaseChangeLog>

それ以外の場合、XPATH 式が正しいことはわかっています。選択基準を に変更すると、そのエントリx:createView[@viewName="myviewnamev"]だけが正しく選択されるからです。changeLog

xmlstarlet を正しく使用するにはどうすればよいends-withですか? または、私がやりたいことを達成する別の方法はありますか?

4

2 に答える 2

5

xmlstarlet機能を提供しない XPath 1.0 のみをサポートしends-with($string, $token)ます。substringこのパターンを使用して独自の文字列を作成するには、string-lengthと および 文字列比較を使用する必要があります。

substring($string, string-length($string) - string-length($token) + 1) = $token]

クエリに適用すると、次のようになります (文字列の長さを「事前計算」しました)。

/x:databaseChangeLog/x:changeSet[x:createView[
  substring(@viewName, string-length(@viewName)) = 'v']
]

または、より強力な XPath 2.0/XQuery エンジンを探すこともできます。

于 2014-02-06T11:52:43.803 に答える