2012-10-01 3 views
0

PubMed (아래 스 니펫)의 여러 XML을 병합하여 만든 SimpleXML 객체가 있지만 병합의 반복이 있습니다. array [] [0], array [] [1] 등 첫 번째 자식 배열을 모두 비교하고 중복 된 것을 버리는 방법은 무엇입니까? 아마도 serialising이 대답 이었지만 SimpleXML Object afaik를 직렬화 할 수는 없지만 ..SimpleXML 다차원 배열을 비교하는 방법은 무엇입니까?

어디에서 시작해야할지 모르겠습니까?

Array 
(
    [0] => Array 
    (
     [title] => SimpleXMLElement Object 
      (
       [0] => Superstructure of the centromeric complex of TubZRC plasmid partitioning systems. 
      ) 

     [link] => SimpleXMLElement Object 
      (
       [@attributes] => Array 
        (
         [Version] => 1 
        ) 

       [0] => 23010931 
      ) 

     [author] => Aylett, CH., Löwe, J. 
     [journal] => SimpleXMLElement Object 
      (
       [0] => Proc. Natl. Acad. Sci. U.S.A. 
      ) 

     [pubdate] => 2012-9-27 
     [day] => SimpleXMLElement Object 
      (
       [0] => 25 
      ) 

     [month] => SimpleXMLElement Object 
      (
       [0] => Sep 
      ) 

     [year] => SimpleXMLElement Object 
      (
       [0] => 2012 
      ) 

    ) 
    [1] => Array 
    (
     [title] => SimpleXMLElement Object 
      (
       [0] => Superstructure of the centromeric complex of TubZRC plasmid partitioning systems. 
      ) 

     [link] => SimpleXMLElement Object 
      (
       [@attributes] => Array 
        (
         [Version] => 1 
        ) 

       [0] => 23010931 
      ) 

     [author] => Aylett, CH., Löwe, J. 
     [journal] => SimpleXMLElement Object 
      (
       [0] => Proc. Natl. Acad. Sci. U.S.A. 
      ) 

     [pubdate] => 2012-9-27 
     [day] => SimpleXMLElement Object 
      (
       [0] => 25 
      ) 

     [month] => SimpleXMLElement Object 
      (
       [0] => Sep 
      ) 

     [year] => SimpleXMLElement Object 
      (
       [0] => 2012 
      ) 

    ) 

은 또한 그것은 초기 XML 병합 단계에서 수행 될 수 - 누구나 중복 제거를 수정하는 방법을 제안 할 수 있다면 나는 순간에 아래의 코드를 사용할 수 있습니까?

function simplexml_merge (SimpleXMLElement &$xml1, SimpleXMLElement $xml2) { 
    $dom1 = new DomDocument(); 
    $dom2 = new DomDocument(); 

    $dom1->loadXML($xml1->asXML()); 
    $dom2->loadXML($xml2->asXML()); 

    $xpath = new domXPath($dom2); 
    $xpathQuery = $xpath->query('/*/*'); 
    for ($i = 0; $i < $xpathQuery->length; $i++) { 
     $dom1->documentElement->appendChild(
     $dom1->importNode($xpathQuery->item($i), true)); 
    } 
    $xml1 = simplexml_import_dom($dom1); 
} 

$xml1 = new SimpleXMLElement($search1); 
$xml2 = new SimpleXMLElement($search2); 

simplexml_merge($xml1, $xml2); 

감사합니다.

... ... 명확성을 위해

는 - 여기에 내가 SimpleXML을로 가져 오기하고있는 XML 소스 레이아웃입니다 - 각 PubmedArticle에는 중복이없는 한 "요소"나는 비교하고 보장에 관심이있다 -

<xml...> 
    <Document> 
     <PubmedArticle> 
      <MedlineCitation> 
       <PMID version="1">xxx</PMID> 
       ... 
      </MedlineCitation> 
      ... 
     </PubmedArticle> 
     <PubmedArticle> 
      <MedlineCitation> 
       <PMID version="1">xxx</PMID> 
       ... 
      </MedlineCitation> 
      ... 
     </PubmedArticle> 
     etc 
    </Document> 
    </xml> 

PMID 노드는 고유하므로 중복 확인에 사용할 수 있습니다. 출력이 합병하기 -

//Get my source XML 
$xml1 = new SimpleXMLElement($search1); 
$xml2 = new SimpleXMLElement($search2); 

//Run through $xml1 and build a query based on it's PMIDs 
$query = array(); 
foreach ($xml1->PubmedArticle as $paper) { 
    $query[] = sprintf('(PMID != %s)',$paper->MedlineCitation->PMID); 
} 
$query = implode('and', $query); 

//Run through $xml2 and get node which don't have PMID matching $xml1 
foreach ($xml2->xpath(sprintf('PubmedArticle/MedlineCitation[%s]', $query)) as $paper) { 
    echo $paper->asXml(); 
} 

그러나 나는 아직도 한 가지 문제를 가지고있다 - @Gordon에서 링크를 사용

... ...

내가 사용을 알고있다. $xml2의 출력에 시작 부분에 '일치'주위에 <PubmedArticle> 노드가 누락되었습니다. 그런 다음 병합을 수행하기 위해 위의 동일한 병합 코드를 사용할 수 있다고 가정합니다. 올바른 방향으로 나를 가리킬 수 있습니까?

+1

http://stackoverflow.com/questions/6640255/show-the-differences-between-2-xml-files-with-php/6641021#6641021 질문에 대한 답변 – Gordon

+0

@Gordon - 대단히 감사합니다. 정말 도움이되었습니다. 나는 하나의 남은 문제가있다. 다시 병합하는 방법을 알려줄 수 있습니까? 두 번째'foreach'에서'echo' 대신에 기존 병합 코드와 비슷한 것을 할 필요가 있습니다. 결과를 추가하기 전에''을 생성하는'addChild'가 필요합니까? – phil

답변

0

XML을 그대로 유지하면서 @ Gordon 's line을 따르기로 결정했습니다. 결국 모든 작업 있어요 :

//function to check 2 xml inputs for duplicate nodes 
    function dedupeXML($xml1, $xml2) { 
     $query = array(); 
     foreach ($xml1->PubmedArticle as $paper) { 
      $query[] = sprintf('(MedlineCitation/PMID != %s)',$paper->MedlineCitation->PMID); 
     } 
     $query = implode('and', $query); 

     $xmlClean = '<Document>'; 
     foreach ($xml2->xpath(sprintf('PubmedArticle[%s]', $query)) as $paper) { 
      $xmlClean .= $paper->asXML(); 
     } 
     $xmlClean .= '</Document>'; 
     $xmlClean = new SimpleXMLElement($xmlClean); 
     return $xmlClean; 
    } 
//function to merge 2 xml inputs 
    function mergeXML (SimpleXMLElement &$xml1, SimpleXMLElement $xml2) { 
     // convert SimpleXML objects into DOM ones 
     $dom1 = new DomDocument(); 
     $dom2 = new DomDocument(); 
     $dom1->loadXML($xml1->asXML()); 
     $dom2->loadXML($xml2->asXML()); 
     // pull all child elements of second XML 
     $xpath = new domXPath($dom2); 
     $xpathQuery = $xpath->query('/*/*'); 
     for ($i = 0; $i < $xpathQuery->length; $i++) { 
      // and pump them into first one 
      $dom1->documentElement->appendChild(
      $dom1->importNode($xpathQuery->item($i), true)); 
     } 
     $xml = simplexml_import_dom($dom1); 
     return $xml; 
    } 

    $xml1 = new SimpleXMLElement($search1); 
    $xml2 = new SimpleXMLElement($search2); 
    $xml3 = new SimpleXMLElement($search3); 
    //dedupe and merge inputs 
    //input 1 & 2 
    $xml2Clean = dedupeXML($xml1, $xml2); 
    $xml12 = mergeXML($xml1, $xml2Clean); 
    //input 1+2 & 3 
    $xml3Clean = dedupeXML($xml12, $xml3); 
    $xml123 = mergeXML($xml12, $xml3Clean); 

이 다른 데이터 소스에 적응하기 쉬운 것을 - 당신의 XML의 데이터 구조를 일치하도록 dedupeXML 기능을 수정합니다.

1

배열로 변환하십시오. (필자에게 쓰지는 않겠지 만, 반복하고 추가하십시오.), array_diff().

+0

병합하기 전에 의미 하시겠습니까? array_diff를 사용하여 각 XML 소스를 배열로 변환하려고 시도했지만 다차원 배열 afaik에서는 작동하지 않습니다. 나는 명백한 것을 놓치고 있는가? – phil

+1

예, 재귀 적으로 작성하거나 이것을 사용해야합니다. 배열 병합 재귀 구분. http://us.php.net/manual/en/function.array-merge-recursive.php#92195 – wesside

관련 문제