XML을 읽고 값만 추출 [중복]

XML을 읽고 값만 추출 [중복]

XML 파일에 설정된 값만 추출하는 가장 간단한 방법은 무엇입니까? 예를 들어 XML 파일의 데이터는 다음과 같습니다.

<node name="host">
  <map>
    <entry key="cipher_strength" value="low" />
    <entry key="port" value="78234" />
    <entry key="over_ssl" value="false" />
    <entry key="using_fips" value="true" />
    <entry key="ssl_keystore" value="lib/ssl" />
  </map>
</node>

low스크립트에서 표시 하고 싶습니다 .

이것은 sed내가 사용하는 명령이며 전체 문자열을 반환합니다.

sed -n '/cipher_strength/{s/.*<cipher_strength>//;s/<\/cipher_strength.*Value=""//;p;}' test.xml

의견에 따르면 xmlstarlet내 수세 버전에서는 사용할 수 없고 공급업체가 잠겨 있어서 설치할 수 없기 때문에 할 수 없습니다.

답변1

명령줄 XML 파서 사용 xmlstarlet:

xmlstarlet sel -t -v '//entry[@key="cipher_strength"]/@value' -nl file.xml

entry이는 XML 문서의 모든 노드와 일치하며 , value동일한 entry노드에 key값이 인 속성이 있는 경우 해당 속성 값이 추출됩니다 cipher_strength. 각 값은 후행 개행 문자와 함께 출력됩니다.

xmllint다양한 시스템에서 사용 가능한 구현은 XPath 쿼리 실행에 대한 지원이 다양한 것으로 보입니다.

내 OpenBSD 시스템에서는 다음을 수행할 수 있습니다.

xmllint --xpath '//entry[@key="cipher_strength"]/@value' file.xml

검색하다

 value="low"

그러나 xmllint --xpath '//entry[@key="cipher_strength"]/@value/text()' file.xml나는 그것이 나에게 string 을 줄 것이라고 기대했지만 low작동하지 않는 것 같습니다(그냥 XPath set is empty응답을 생성할 뿐입니다).

속성 값이 "nice" 이면 value이 출력을 처리하여 실제 값을 추출할 수 있습니다.

$ xmllint --xpath '//entry[@key="cipher_strength"]/@value' file.xml | sed -e 's/^[^"]*"//' -e 's/"$//'
low

위의 표현식은 sed각 줄에서 첫 번째 큰따옴표 문자까지 모든 것을 제거한 다음 마지막 큰따옴표 문자도 자릅니다.

다른 xmllint구현/버전에서는 다음 접근 방식을 채택했을 수 있습니다 xmllint --shell.

xmllint --shell file.xml <<<'cat //entry[@key="cipher_strength"]/@value' |
sed -e '/^[^ ]/d' -e 's/^[^"]*"//' -e 's/"$//'

답변2

전용 XML 도구를 사용할 수 없는 경우 다음을 사용해 볼 수 있습니다 awk.

user@host~$ awk '/key="cipher_strength"/ {for (i=1;i<=NF;i++) { if (split($i,parts,"=")==2 && parts[1]=="value") print parts[2]}}' file.xml

공백으로 구분된 모든 문자열을 포함하는 줄을 찾은 key="cipher_strength"다음 공백으로 구분된 모든 문자열은 기호에서 분할됩니다 =. "중간"에 이 기호가 포함된 모든 기호에 대해(즉, 앞에 부분이 있고 뒤에 부분이 있음) 첫 번째 부분이 같은지 확인 value하고 그렇다면 두 번째 부분을 인쇄합니다. 귀하의 의견에 대해 나는

user@host~$ awk '/key="cipher_strength"/ {for (i=1;i<=NF;i++) { if (split($i,parts,"=")==2 && parts[1]=="value") print parts[2]}}' file.xml
"low"

노드 가 더 많은 경우 <node>이 작업을 적용하기 전에 프로그램을 수정하여 올바른 위치에 있는지 확인할 수 있습니다.

관련 정보