Вставить [$ _POST] var в строку поиска DOM? - PullRequest
1 голос
/ 22 ноября 2010

Я не уверен, правильно ли я назвал этот заголовок, но в основном у меня есть переменная из $ _POST (имя группы), и я хочу вставить ее вместо имени узла в строке, подобной этой:

$lastvisits = $address->$band->getElementsByTagName("lastvisit");

, где $band - это

$band = $_POST['band']

, потому что узел внутри $ address может быть действительно любым именем и может не существовать.Я уверен, что должен быть простой способ, но я не уверен в форматировании.

Если он существует или его нет, $ lastvisits = $ address -> $ band> getElementsByTagName ("lastvisit") выдает ошибку - Фатальная ошибка : вызов функции-члена getElementsByTagName () для необъекта в ...

XML-

<?xml version="1.0"?>
<addresses>
<address>
    <ip>127.0.0.1</ip>
    <Beatles>
        <lastvisit>12/08/2006</lastvisit>
    </Beatles>
</address>
    <address>
    <ip>125.0.0.1</ip>
</address>
 </addresses>

Это полный код:

    $doc = new DOMDocument();
$doc->load("votingxml/addresses.xml");
$addresses = $doc->getElementsByTagName("address");
$band = strval($_POST['band']);
$pVoted = false;
$pFound = false;

//Loop through the addresses nodes and see if the person has voted before for each( $addresses as $address )
{

$ips = $address->getElementsByTagName("ip");
            $ip = $ips->item(0)->nodeValue;
                            if ($ip == $domain){

                $pFound = true;             
            if ($address->$band == 'NULL'){
                 $bandfound= false;
                 $newBandElement = $doc->createElement($_POST['band']);
                 $newLastVisitElement = $doc->createElement('lastvisit');
                 $dayvalue = $doc->createTextNode($today);
                 $dayvalue = $newLastVisitElement->appendChild($dayvalue);

                 $newBandElement->appendChild($newLastVisitElement);
                 $address->appendChild($newBandElement);
                 $doc->save("votingxml/addresses.xml");
                 $pVoted = false;
            }
            else{

                 $bandfound =true;
                                 $lastvisits = $address->$band->getElementsByTagName("lastvisit");
                 $lastvisit = $lastvisits->item(0)->nodeValue;

                 if ($lastvisit == $today){
                        echo "alreadyvoted";
                        $pVoted = true;
                     }else{
                    $lastvisits->item(0)->nodeValue = $today;
                    $doc->save("votingxml/addresses.xml");
                    $pVoted = false;
                     }

            }
        }
        else if ($ip != $domain)
        {
            $pFound = false;
        }

}

Любая помощь будет принята с благодарностью.

1 Ответ

1 голос
/ 22 ноября 2010

Edit # 1 : Похоже, вы ссылаетесь на DOM в добавленном примере, а не на SimpleXML. Тем не менее, вот как вы это делаете с объектами SimpleXML, используя вашу структуру XML ...


$band = $_POST['band'];

if (property_exists($address, $band)) {
    $lastvisits = $address->$band->lastvisit;
}
else {
    /* handle the fact that the name of the element which the user passed is invalid */
}

Примечание: есть только 1 элемент lastvisit. Если их будет больше, вам нужно будет обернуть эти элементы lastvisit в один родительский элемент «lastvisit» в XML-файле. Допустимый XML и все такое.

Редактировать # 2 : есть некоторые проблемы с вашей структурой xml. «Битлз» слишком уникален, чтобы называться именем элемента. Вы можете изменить это так:

<addresses>
   <address>
      <ip>127.0.0.1</ip>
      <visits>
         <visit>
            <band>Beatles</band>
            <lastvisit>12/08/2006</lastvisit>
         </visit>
         <visit>
            <band>New Kids On the Block</band>
            <lastvisit>1/14/2008</lastvisit>
         </visit>
      </visits>
   </address>
   <address>
      <ip>24.135.9.2</ip>
      <visits>
...
      </visits>
   </address>
</addresses>

Затем вам нужно будет найти узел ip со значением IP, который вы хотите найти, затем под узлом band для значения "Beatles".

Редактирование # 3, 4: Добавление метода для DOM с использованием класса DOMXPath для запуска поиска по вышеуказанной структуре XML и добавление новой записи, если полоса не найдена ...


$band = $_POST['band'];
$client_IP = $_SERVER["REMOTE_ADDR"];
$doc = new DOMDocument();
$doc->load("votingxml/addresses.xml");
$xpath = new DOMXPath($doc);
$ip_query = $xpath->query('//addresses/address/ip[. = "' . $client_IP . '"]');
if ($ip_query->length === 1) {
    // client's IP found, now grab and work with the client's address record
    $address = $ip_query->item(0)->parentNode;
    // search for the visit record within $address for band element value = $band
    $band_query = $xpath->query('visits/visit/band[. = "'.$band.'"]', $address);
    if ($band_query->length === 1) {
        // $band found, now get visit parent record for more details
        $visit = $band_query->item(0)->parentNode;
        // with that, now do something with the record's lastvisit value
        echo $visit->getElementsByTagName("lastvisit")->item(0)->nodeValue;
        }
    else {
        // $band not found.  Add new visit record to the XML file
        // point to 'visits' group element
        $visits = $address->getElementsByTagName("visits")->item(0);
        // create a new 'visit' element, complete with 'band' and 'lastvisit' child elements
        $visit = $doc->createElement("visit");
        $band = $doc->createElement("band", $band);
        $lastvisit = $doc->createElement("lastvisit", date("n/d/Y"));
        $visit->appendChild($band);
        $visit->appendChild($lastvisit);
        // now add new 'visit' element to 'visits' element and save
        $visits->appendChild($visit);
        $doc->save("votingxml/addresses.xml");
        }
    }
...