2009-03-18 3 views
3

나는 내가 XML을 얻기 위해 사용하고 어제 How do I retrieve tag attributes with XML::Simple? 링크 질문을 :하나 이상의 하위 요소가있을 수있는 XML 태그로 XML :: Simple을 어떻게 사용할 수 있습니까?

http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&id=19273512 (1)

(2)

내가 아주 좋은 진전을 만들어 통해 루프 다음과 같은 코드를 작성 http://eutils.ncbi.nlm.nih.gov/entrez/eutils/esummary.fcgi?db=pubmed&id=19291509 필요한 태그를 검색하고 검색합니다. 나는 아래의 '도이'태그를 찾고 있어요 'ArticleIds'

foreach $item_node (@{$dataSummary->{DocSum}->{Item}}) 
     { 
       if($item_node->{Name} eq 'ArticleIds') 
       { 
         foreach $item_node1 (@{$item_node->{Item}}) 
         { 
           if ($item_node1->{Name} eq 'doi') 
           { 
            $doi= $item_node1->{content}; 
            last; 
           } 
         } 
         last; 

       } 
     } 

이 코드는 기본적으로 ArticleIds 태그를 검색 한 후 '도이'태그를 찾아 그 아래에 하위 태그를 검색합니다.

문제 ArticleIds에 (2)에서 볼 수있는 것처럼 여러 개의 하위 태그가있는 경우 모든 항목이 올바르게 작동합니다. 그러나 ArticleIds 태그에는 (1)에서와 같이 하나의 하위 태그 만있을 때 오류가 발생하고 프로그램이 중지됩니다.

나는 간단한 파서를 사용하고 있으며 덤퍼를 사용하여 두 가지 결과를 얻었습니다. 은 여기에 (2)

{ 'Type' => 'List', 'Item' => [ { 'Type' => 'String', 'content' => '909564644', 'Name' => 'pii' }, { 'Type' => 'String', 'content' => '10.1080/13506120802676914', 'Name' => 'doi' }, { 'Type' => 'String', 'content' => '19291509', 'Name' => 'pubmed' } ], 'Name' => 'ArticleIds' } 

당신이 볼 수 있듯이 링크에 대한 링크 (1)에 대한 덤프 의 일부

{ 'Type' => 'List', 'Item' => { 'Type' => 'String', 'content' => '19273512', 'Name' => 'pubmed' }, 'Name' => 'ArticleIds' } 

입니다. ArticleIds 아래에 여러 개의 태그가있을 경우 배열로 처리되므로 대괄호로 처리됩니다.

누군가이 경우에 무엇을 제안합니까?

답변

6

파일에 Item 요소 중 하나만 있으면 해당 항목이 해시로 표시됩니다. 여러 개의 Item 요소가있는 경우 배열로 표시됩니다. 특정 태그가 항상 ForceArray 옵션을 사용하여 목록을 포함하도록 할 수 있습니다. 배열에 강제 적용하려는 모든 속성 이름의 정규 표현식을 전달하면 나머지는 처리합니다.

XMLin('file.xml', 
     ForceArray => qr{Item}x); 

아, 사용중인 XML :: Simple 버전도 확인하십시오. 이전 버전에서는 ForceArray를 사용하여 값의 배열 참조 만 지정할 수 있다고 생각합니다. 그렇지 않으면 전혀 작동하지 않습니다. 밖으로 The XML::Simple CPAN documentation 당신을 도울 수 있습니다 더 많은 옵션을 볼 수

XMLin('file.xml', 
     ForceArray => [ 'Item' ]); 

확인 : 그것은 단지 arrayref으로 작동하는 경우, 당신은 그것을 지정할 수 있습니다.

버전까지는 ActiveState 배포판과 함께 제공된 XML :: Simple을 사용하는 경우 버전이 오래되었을 가능성이 큽니다. 새로운 것을 움켜 잡으십시오.

또한 그것이 어떤 종류의 확인, 중 (당신이 발견으로)

ref($item) eq 'HASH' 
ref($item) eq 'ARRAY' 
+0

나는 하나의 항목 만 있으면 다음과 같이했습니다. 그것은 해시로 올 것입니다. $ contents = get ($ getstring) $ data = $ xml-> XMLin ($ contents, ForceArray => qr {Item} x); –

+0

내가 ItemIds 태그에 배열에 넣고 싶은 Item 태그가 있기 때문에 뭔가 다른 점이 있습니까? –

+0

이것은 실망 스럽습니다 ... :(XML :: Simple 버전을 찾으려면 빠른 방법이 있습니까? –

4

난 당신이하고있는 문제 중 하나라고 생각

$item =~ /HASH/ # hash 
$item =~ /ARRAY/ # array 

또는 심판 키워드를 사용 할 수 있습니다 XML :: Simple 사이에 당신이 충분한 노브와 다이얼을 제공하지 못하는 것이지만, 문제는 좀 더 복잡한 것을 작성하기에 충분히 복잡하지 않습니다.

이 경우에는 XML::Twig과 같은 항목이 표시됩니다. 더 많은 이벤트가 구동되어 XML을 거쳐 원하는 시점에 제어 할 수 있습니다. 일단 당신이 좋아하는 요소를 얻으면, 당신이 좋아하는 것을 무엇이든 할 수 있습니다.

Twig 같은 것 외에도 XPath와 같은 다양한 것들이 같은 방식으로 유용 할 수 있습니다. 그것들은 데이터 구조를 제공하는 XML :: Simple과 달리 XML의 일부를 추출하기 위해 XML을 심층적으로 조사하기 위해 만들어졌습니다.

1

나는 XML에 oldver 버전을 가지고있다 :: Simple 그래서 ref() 함수를 사용하고 코드 몇 줄을 추가하기로했다.

도움을 주셔서 감사합니다

+0

나는 보통 그것을 처리한다. –

관련 문제