예:-
<item href="cover.jpeg" id="cover" media-type="image/jpeg"/>
@id="cover" 및 media-type="image/*"를 선택하고 @href를 검색하고 싶습니다.
xmlstarlet sel -t -m "//_:item[@id='$opf_cover_name']" -v @href -o '|' -v @media-type -n file.xml
내 현재 "솔루션"은 - 다음과 같이 "|" 문자 주위에 출력이 매우 혼란스럽게 분할되는 것 같습니다 .
Does xmlstarlet have a substring function?
Version = 1.6.1
compiled against libxml2 2.9.4, linked with 20904
compiled against libxslt 1.1.29, linked with 10132
답변1
the_id='cover'
the_mediatype_prefix='image/'
xmlstarlet sel -t \
--var queryid="'$the_id'" \
--var typeprefix="'$the_mediatype_prefix'" \
-v '//item[@id = $queryid and starts-with(@media-type, $typeprefix)]/@href' \
-nl file.xml
이는 두 개의 셸 변수를 사용하여 XML 파일을 쿼리합니다. 이 the_id
변수에는 id
필터링하려는 속성 값과 the_mediatype_prefix
속성이 시작해야 하는 문자열도 포함되어 있습니다.media-type
xmlstarlet
도구의 옵션을 사용하기 위해 두 개의 내부 변수를 만듭니다 --var
. 이러한 값은 인코딩된 값이어야 하므로 주위에 작은따옴표를 삽입했습니다(이것은 약간 번거롭습니다. 이상적으로는 XPath 문자열을 올바르게 인코딩해야 하지만 쉘 변수를 표현식에 직접 삽입하는 것보다 낫습니다).
XPath 표현식은 합이 일치하는 각 노드의 속성을 선택합니다 href
.item
id
media-type
사용 xq
(XML 파서 래퍼 around jq
, JSON 파서):
the_id='cover'
the_mediatype_prefix='image/'
xq -r \
--arg queryid "$the_id" \
--arg typeprefix "$the_mediatype_prefix" '
.. | .item? |
select(
."@id" == $queryid and
(."@media-type" | startswith($typeprefix))
)."@href"' file.xml
xmlstarlet
jq
XPath 쿼리 대신 표현식을 사용한다는 점을 제외하면 이는 거의 동일한 코드입니다. 여기에서 유틸리티는 따옴표와 같은 불안정한 값이 포함된 경우에도 쉘 변수를 올바르게 인코딩해야 합니다(예제의 쉘 변수 값에 xmlstarlet
잘못된 문자 시퀀스가 포함된 경우 수동으로 인코딩해야 합니다).
답변2
여러 조건을 추가할 수 있습니다.
xmlstarlet sel -t -m "//item[@id='cover'][starts-with(@media-type,'image/')]" -v '@href' -nl file.xml