2014-02-06 3 views
2

나는 viewName이 "v"로 끝나는 XML changelog에서 을 사용하여 changeSet 개의 노드를 추출합니다. 그러나 왜 xmlstarlet은 'ends-with'기능이 없다고 말합니까?

, xmlstarlet는 ends-with XPATH 기능이 존재하지 않는다고 불평 :

<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 표현 그렇지 않으면 정확하다는 것을 알고있다 :

$ 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이 같은 비트 보이는 왜냐하면 선택 기준을 x:createView[@viewName="myviewnamev"]으로 변경하면 정확히 changeLog 항목 만 선택하기 때문입니다.

xmlstarlet에서 ends-with을 올바르게 사용하려면 어떻게해야합니까? 아니면 내가하고 싶은 것을 성취 할 수있는 또 다른 방법이 있습니까?

+0

[XPath 사양] (http://www.w3.org/TR/xpath/)에서 'ends-with'기능은 어디에서 볼 수 있습니까? –

+0

@ O.R.Mapper right [here] (http://www.w3.org/TR/xquery-operators/#func-ends-with) 그러나 아래의 Jens의 대답은 xmlstarlet이 XPath 2.0을 지원하지 않는다는 것을 명확히했습니다. – Jonathan

+0

사실, 정확하게. –

답변

3

xmlstarletends-with($string, $token) 기능을 제공하지 않는 XPath 1.0 만 지원합니다. 그것은이 (I "미리 계산 된"문자열 길이)과 같아야합니다

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

가 쿼리에 적용 : 당신은이 패턴을 사용하여 자신을 구성 substring, string-length 및 및 문자열 비교를 사용할 필요가

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

또는 더 강력한 XPath 2.0/XQuery 엔진을 찾고 싶을 수도 있습니다.

+0

감사합니다. 일회성이므로이 솔루션은 훌륭합니다. – Jonathan