0

PubMed (以下のスニペット) から複数の XML をマージして作成した SimpleXML オブジェクトがありますが、マージからの繰り返しがあります。最初のすべての子配列 (array[][0]、array[][1] など) を比較し、重複を破棄するにはどうすればよいですか? おそらくシリアル化が答えでしたが、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 は、比較して重複がないことを確認することに関心のある 1 つの「要素」です。

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

PMID ノードは一意であるため、重複のチェックに使用できます。

... ... ...

@Gordon からのリンクを使用 - 私は使用を知っています:

//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();
}

ただし、まだ 1 つの問題があります。出力をマージすることです。の出力には、最初の各「一致」の周り$xml2のノードがありません。<PubmedArticle>次に、同じマージ コード (上記) を使用してマージを実行できると思います。正しい方向に私を向けることができますか?

4

2 に答える 2

1

それを配列に変換します (私はあなたのために書くつもりはありません。反復して追加するだけです) array_diff()

于 2012-10-01T13:41:25.287 に答える
0

@Gordonの行をXMLのままにしておくことにしました。最終的にすべてが機能するようになりました。

//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);

これは他のデータソースに簡単に適応できdedupeXMLます。XMLのデータ構造に一致するように関数を変更するだけです。

于 2012-10-11T08:45:46.817 に答える