2017-02-14 8 views
0

많은 미디어 필드가있는 XML 파일이 있습니다. XML 예제는 다음과 같습니다.xmllint를 사용하여 여러 개의 동일한 필드를 추출합니다.

<root> 
    <item> 
     <name>Item 1</name> 
     <mediaList> 
      <media> 
       <name>Name 1</name> 
       <URL><![CDATA[http://example.com/image1.jpg]]></URL> 
      </media> 
      <media> 
       <name>Name 2</name> 
       <URL><![CDATA[http://example.com/image2.jpg]]></URL> 
      </media> 
     </mediaList> 
    </item> 
    <item> 
     <name>Item 2</name> 
     <mediaList> 
      <media> 
       <name>Name 3</name> 
       <URL><![CDATA[http://example.com/image3.jpg]]></URL> 
      </media> 
      <media> 
       <name>Name 4</name> 
       <URL><![CDATA[http://example.com/image4.jpg]]></URL> 
      </media> 
     </mediaList> 
    </item> 
</root> 

모든 항목이 같은 방식으로 작성됩니다. XPath에서 XMLLint를 사용하여 모든 URL의 목록을 가져 오려고합니다. 그러나, 지금까지, 나는 그것에 대해 아직 갈 가장 좋은 방법을 찾지 못했습니다. 나는 그것을 시도했습니다 몇 가지 방법은 다음과 같습니다

xmllint --xpath "string(/root/item/mediaList/URL)" file.xml >> log.txt

이 하나가 좋은 URL을 반환하지만

xmllint --xpath "/root/item/mediaList/URL" file.xml >> log.txt

이 (나에게 단 한 이미지를주는) 첫 번째 항목 후에 중지 모든 항목을 제공하지만 모든 항목이 같은 줄에 있으며 각 항목에 대해 <URL><![CDATA[http://example.com/image.jpg]]></URL>으로 표시됩니다.

xmllint --xpath "/root/item/mediaList/URL/text()" file.xml >> log.txt

이에 가장 가까운,하지만 여전히 주위에 <![CDATA[]]> 태그를 반환하고 다시 모두 한 줄입니다.

또한 항목을 반복하면서 시도했지만 매우 느려서 정상적으로 작동하지 않았습니다. W3C의 문서에서, 나는 당신이 파서를 변경해야한다고 생각

http://example.com/image1.jpg 
http://example.com/image2.jpg 
http://example.com/image3.jpg 
http://example.com/image4.jpg 
+1

'--nocdata' 옵션은 각 CDATA 노드에서 텍스트를 추출합니다. 그래도 각 URL을 별도의 줄에 가져 오는 방법을 모르겠습니다. – chepner

+0

감사합니다. 좋은거야. 생각할 문제가 하나 더 적습니다. –

답변

2

xmllint은 복수의 XPath 일치 항목에 대해 string(...)을 지원하지 않습니다. (따라서 첫 번째 결과 만 표시됩니다.)

당신은 같은 xmlstarlet 사용할 수 있습니다

xmlstarlet sel -T -t -m /root/item/mediaList/media/URL -v . -n file.xml 

을 그리고로 (설치된 XML::LibXML 모듈)도

http://example.com/image1.jpg 
http://example.com/image2.jpg 
http://example.com/image3.jpg 
http://example.com/image4.jpg 

또는 펄을 생성합니다

perl -MXML::LibXML -E 'say $_->to_literal for XML::LibXML->load_xml(location=>q{file.xml})->findnodes(q{/root/item/mediaList/media/URL})' 

도 같은 결과를 위와 같이.

+0

'xmlstarlet' 옵션이 저에게 그것을 해결했습니다. 고맙습니다. –

0

:

내가 목표로하고있어 그 결과의 TXT과 같이 서로 아래의 모든 이미지 파일입니다

각 CDATA 섹션 내의 문자는 문자 데이터로 취급됩니다. 따라서 소스 문서의 <! [CDATA [<]]>은 <과 동일하게 취급됩니다. 둘 다 트리의 텍스트 노드에 단일 < 문자가 표시됩니다. 따라서 CDATA 섹션은 마치 <! [CDATA [및]]> 이 제거 된 것처럼 취급되며 < 및 &이 모두 각각 < 및 &으로 대체되었습니다. CDATA가 자동으로 제거됩니다

, 나는 파이썬에서 테스트 :

tree = etree.fromstring(xml) 
tree.xpath('//URL/text()') 

아웃 :

['http://example.com/image1.jpg', 
'http://example.com/image2.jpg', 
'http://example.com/image3.jpg', 
'http://example.com/image4.jpg'] 

귀하의 XPath가 올바른지.