복붙노트

PHP에서 XMLReader를 사용하는 방법?

PHP

PHP에서 XMLReader를 사용하는 방법?

내가 다음과 같은 XML 파일을 가지고, 파일이 오히려 커지고 PHP에서 성공과 XMLReader를 시도하고 그래서 파일을 열고 열려면 simplexml을 얻을 수 없었어요

<?xml version="1.0" encoding="ISO-8859-1"?>
<products>
    <last_updated>2009-11-30 13:52:40</last_updated>
    <product>
        <element_1>foo</element_1>
        <element_2>foo</element_2>
        <element_3>foo</element_3>
        <element_4>foo</element_4>
    </product>
    <product>
        <element_1>bar</element_1>
        <element_2>bar</element_2>
        <element_3>bar</element_3>
        <element_4>bar</element_4>
    </product>
</products>

불행히도 PHP에 대한 좋은 자습서를 찾지 못했고 각 요소 컨텐츠를 데이터베이스에 저장할 수있는 방법을 알고 싶습니다.

해결법

  1. ==============================

    1.그것은 모두 작업 단위의 크기에 따라 다르지만, 각 노드를 연속적으로 처리하려고합니다.

    그것은 모두 작업 단위의 크기에 따라 다르지만, 각 노드를 연속적으로 처리하려고합니다.

    이를 위해 가장 간단한 방법은 XMLReader를 사용하여 각 노드에 도달 한 다음 SimpleXML을 사용하여 노드에 액세스하는 것입니다. 이렇게하면 한 번에 하나의 노드 만 처리하고 여전히 SimpleXML의 사용 편의성을 활용하므로 메모리 사용량을 낮게 유지할 수 있습니다. 예를 들면 :

    $z = new XMLReader;
    $z->open('data.xml');
    
    $doc = new DOMDocument;
    
    // move to the first <product /> node
    while ($z->read() && $z->name !== 'product');
    
    // now that we're at the right depth, hop to the next <product/> until the end of the tree
    while ($z->name === 'product')
    {
        // either one should work
        //$node = new SimpleXMLElement($z->readOuterXML());
        $node = simplexml_import_dom($doc->importNode($z->expand(), true));
    
        // now you can use $node without going insane about parsing
        var_dump($node->element_1);
    
        // go to next <product />
        $z->next('product');
    }
    

    다양한 접근 방식의 장단점에 대한 간략한 개요 :

    XMLReader 전용

    XMLReader + SimpleXML

    XMLReader + DOM

    나의 조언 : SimpleXML로 프로토 타입을 작성하고, 그것이 당신을 위해 작동하는지 확인하십시오. 성능이 가장 중요한 경우 DOM을 사용해보십시오. 가능한 한 XMLReader와 멀리 떨어져 있어야합니다. 작성한 코드가 많을수록 버그를 도입하거나 성능 회귀를 일으킬 가능성이 높아집니다.

  2. ==============================

    2.XML 형식의 속성으로 서식 설정 ...

    XML 형식의 속성으로 서식 설정 ...

    data.xml :

    <building_data>
    <building address="some address" lat="28.902914" lng="-71.007235" />
    <building address="some address" lat="48.892342" lng="-75.0423423" />
    <building address="some address" lat="58.929753" lng="-79.1236987" />
    </building_data>
    

    PHP 코드 :

    $reader = new XMLReader();
    
    if (!$reader->open("data.xml")) {
        die("Failed to open 'data.xml'");
    }
    
    while($reader->read()) {
      if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'building') {
        $address = $reader->getAttribute('address');
        $latitude = $reader->getAttribute('lat');
        $longitude = $reader->getAttribute('lng');
    }
    
    $reader->close();
    
  3. ==============================

    3.대부분의 XML 파싱 수명은 XML (Amazon MWS)의 트럭로드에서 유용한 정보를 추출하는 데 소비됩니다. 따라서, 내 대답은 당신이 특정 정보만을 원한다고 가정하고 그 정보의 위치를 ​​압니다.

    대부분의 XML 파싱 수명은 XML (Amazon MWS)의 트럭로드에서 유용한 정보를 추출하는 데 소비됩니다. 따라서, 내 대답은 당신이 특정 정보만을 원한다고 가정하고 그 정보의 위치를 ​​압니다.

    XMLReader를 사용하는 가장 쉬운 방법은 정보를 원하는 태그를 알고 사용하는 것입니다. XML의 구조를 알고 있고 고유 한 태그가 많이있는 경우 첫 번째 경우를 사용하는 것이 쉽다는 것을 알게되었습니다. 사례 2와 3은 복잡한 태그에 대해 어떻게 수행 할 수 있는지 보여줍니다. 이것은 매우 빠릅니다. 나는 PHP에 관한 가장 빠른 XML 파서는 무엇인가?

    이와 같이 태그 기반 파싱을 할 때 기억해야 할 가장 중요한 점은 if ($ myXML-> nodeType == XMLReader :: ELEMENT) {... - 우리가 노드를 여는 것만을 확인하고 공백이나 닫는 노드가 아니어도 상관 없습니다.

    function parseMyXML ($xml) { //pass in an XML string
        $myXML = new XMLReader();
        $myXML->xml($xml);
    
        while ($myXML->read()) { //start reading.
            if ($myXML->nodeType == XMLReader::ELEMENT) { //only opening tags.
                $tag = $myXML->name; //make $tag contain the name of the tag
                switch ($tag) {
                    case 'Tag1': //this tag contains no child elements, only the content we need. And it's unique.
                        $variable = $myXML->readInnerXML(); //now variable contains the contents of tag1
                        break;
    
                    case 'Tag2': //this tag contains child elements, of which we only want one.
                        while($myXML->read()) { //so we tell it to keep reading
                            if ($myXML->nodeType == XMLReader::ELEMENT && $myXML->name === 'Amount') { // and when it finds the amount tag...
                                $variable2 = $myXML->readInnerXML(); //...put it in $variable2. 
                                break;
                            }
                        }
                        break;
    
                    case 'Tag3': //tag3 also has children, which are not unique, but we need two of the children this time.
                        while($myXML->read()) {
                            if ($myXML->nodeType == XMLReader::ELEMENT && $myXML->name === 'Amount') {
                                $variable3 = $myXML->readInnerXML();
                                break;
                            } else if ($myXML->nodeType == XMLReader::ELEMENT && $myXML->name === 'Currency') {
                                $variable4 = $myXML->readInnerXML();
                                break;
                            }
                        }
                        break;
    
                }
            }
        }
    $myXML->close();
    }
    
  4. ==============================

    4.XMLReader는 PHP 사이트에서 잘 설명되어 있습니다. 이것은 XML Pull Parser로 주어진 XML 문서의 노드 (또는 DOM 노드)를 반복하는 데 사용됩니다. 예를 들어, 이렇게 준 문서 전체를 살펴볼 수 있습니다.

    XMLReader는 PHP 사이트에서 잘 설명되어 있습니다. 이것은 XML Pull Parser로 주어진 XML 문서의 노드 (또는 DOM 노드)를 반복하는 데 사용됩니다. 예를 들어, 이렇게 준 문서 전체를 살펴볼 수 있습니다.

    <?php
    $reader = new XMLReader();
    if (!$reader->open("data.xml"))
    {
        die("Failed to open 'data.xml'");
    }
    while($reader->read())
    {
        $node = $reader->expand();
        // process $node...
    }
    $reader->close();
    ?>
    

    XMLReader :: expand ()가 반환 한 노드를 처리하는 방법은 사용자가 결정해야합니다.

  5. ==============================

    5.

    Simple example:
    
    public function productsAction()
    {
        $saveFileName = 'ceneo.xml';
        $filename = $this->path . $saveFileName;
        if(file_exists($filename)) {
    
        $reader = new XMLReader();
        $reader->open($filename);
    
        $countElements = 0;
    
        while($reader->read()) {
            if($reader->nodeType == XMLReader::ELEMENT) {
                $nodeName = $reader->name;
            }
    
            if($reader->nodeType == XMLReader::TEXT && !empty($nodeName)) {
                switch ($nodeName) {
                    case 'id':
                        var_dump($reader->value);
                        break;
                }
            }
    
            if($reader->nodeType == XMLReader::END_ELEMENT && $reader->name == 'offer') {
                $countElements++;
            }
        }
        $reader->close();
        exit(print('<pre>') . var_dump($countElements));
        }
    }
    
  6. ==============================

    6.받아 들여진 응답은 나에게 좋은 시작을 주었지만, 내가 좋아했을 것보다 더 많은 수업과 처리를 가져왔다. 그래서 이것이 제 해석입니다.

    받아 들여진 응답은 나에게 좋은 시작을 주었지만, 내가 좋아했을 것보다 더 많은 수업과 처리를 가져왔다. 그래서 이것이 제 해석입니다.

    $xml_reader = new XMLReader;
    $xml_reader->open($feed_url);
    
    // move the pointer to the first product
    while ($xml_reader->read() && $xml_reader->name != 'product');
    
    // loop through the products
    while ($xml_reader->name == 'product')
    {
        // load the current xml element into simplexml and we’re off and running!
        $xml = simplexml_load_string($xml_reader->readOuterXML());
    
        // now you can use your simpleXML object ($xml).
        echo $xml->element_1;
    
        // move the pointer to the next product
        $xml_reader->next('product');
    }
    
    // don’t forget to close the file
    $xml_reader->close();
    
  7. ==============================

    7.이 주제는 오래 전에 끝났지 만 방금 발견했습니다. 하나님 감사합니다.

    이 주제는 오래 전에 끝났지 만 방금 발견했습니다. 하나님 감사합니다.

    문제는 ONIX 파일 (서적 데이터)을 읽고 데이터베이스에 저장해야한다는 것입니다. 전에는 simplexml_load를 사용하고 있지만 메모리는 많이 사용했지만 상대적으로 작은 파일 (최대 300MB)은 여전히 ​​괜찮습니다. 그 크기를 넘어선 저에게는 재앙입니다.

    특히 Francis Lewis의 해석을 읽은 후에, 저는 xmlreader와 simplexml의 조합을 사용합니다. 결과는 예외적인데, 메모리 사용량이 적어서 데이터베이스에 충분히 빨리 삽입됩니다.

    여기 내 코드가 있습니다 :

    <?php
    $dbhost = "localhost"; // mysql host
    $dbuser = ""; //mysql username
    $dbpw = ""; // mysql user password
    $db = ""; // mysql database name
    
    //i need to truncate the old data first
    $conn2 = mysql_connect($dbhost, $dbuser, $dbpw);
    mysql_select_db($db);
    mysql_query ("truncate ebiblio",$conn2);
    //$xmlFile = $_POST['xmlFile'];
    //$xml=simplexml_load_file("ebiblio.xml") or die("Error: Cannot create    object");
    
    $reader = new XMLReader();
    
    //load the selected XML file to the DOM
    if (!$reader->open("ebiblio.xml")) {
    die("Failed to open 'ebiblio.xml'");
    }
    
    while ($reader->read()):
    
    if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'product'){
            $xml = simplexml_load_string($reader->readOuterXML());
            $productcode = (string)$xml->a001;
            $title = (string)$xml->title->b203;
            $author = (string)$xml->contributor->b037;
            $language = (string)$xml->language->b252;
            $category = $xml->subject->b069;
            $description = (string)$xml->othertext->d104;
            $publisher = (string)$xml->publisher->b081;
            $pricecover = (string)$xml->supplydetail->price->j151;
            $salesright = (string)$xml->salesrights->b090;
    
            @$productcode1 = htmlentities($productcode,ENT_QUOTES,'latin1_swedish_ci');
            @$title1 = htmlentities($title,ENT_QUOTES,'latin1_swedish_ci');
            @$author1 = htmlentities($author,ENT_QUOTES,'latin1_swedish_ci');
            @$language1 = htmlentities($language,ENT_QUOTES,'latin1_swedish_ci');
            @$category1 = htmlentities($category,ENT_QUOTES,'latin1_swedish_ci');
            @$description1 = htmlentities($description,ENT_QUOTES,'latin1_swedish_ci');
            @$publisher1 = htmlentities($publisher,ENT_QUOTES,'latin1_swedish_ci');
            @$pricecover1 = htmlentities($pricecover,ENT_QUOTES,'latin1_swedish_ci');
            @$salesright1 = htmlentities($salesright,ENT_QUOTES,'latin1_swedish_ci');
    
            $conn = mysql_connect($dbhost, $dbuser, $dbpw);
            mysql_select_db($db);
    
            $sql = "INSERT INTO ebiblio VALUES ('" . $productcode1 . "','" . $title1 . "','" . $author1 . "','" . $language1 . "','" . $category1 . "','" . $description1 . "','" . $publisher1 . "','" . $pricecover1 . "','" . $salesright1 . "')";
    
            mysql_query($sql, $conn);
            $reader->next('product');
    
    }
    
    
    endwhile;
    ?>
    
  8. from https://stackoverflow.com/questions/1835177/how-to-use-xmlreader-in-php by cc-by-sa and MIT license