Как я могу получить значение атрибута узла xml в php?

Я использую simplexml для чтения XML-файла. Пока я не могу получить значение атрибута, которое я ищу. это мой код.

          if(file_exists($xmlfile)){
              $doc = new DOMDocument();
              $doc->load($xmlfile);
              $usergroup = $doc->getElementsByTagName( "preset" );
              foreach($usergroup as $group){         
                 $pname = $group->getElementsByTagName( "name" );
                 $att = 'code';
                 $name = $pname->attributes()->$att; //not working

                 $name = $pname->getAttribute('code'); //not working
                 if($name==$preset_name){
                     echo($name);
                      $group->parentNode->removeChild($group);
                 }
              }
          }

и мой xml-файл выглядит так

<presets>
<preset>
 <name code="default">Default</name>
  <createdBy>named</createdBy>
  <icons>somethignhere</icons>
 </preset>
</presets>

person guitarlass    schedule 27.04.2012    source источник


Ответы (2)


Попробуйте это:

function getByPattern($pattern, $source)
{
    $dom = new DOMDocument();
    @$dom->loadHTML($source);

    $xpath = new DOMXPath($dom);
    $result = $xpath->evaluate($pattern);

    return $result;
}

И вы можете использовать его как (используя XPath) :

$data = getByPattern("/regions/testclass1/presets/preset",$xml);

ОБНОВИТЬ


Код:

<?php
    $xmlstr = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><presets><preset><name code=\"default\">Default</name><createdBy>named</createdBy><icons>somethignhere</icons></preset></presets>";

    $xml = new SimpleXMLElement($xmlstr);

    $result = $xml->xpath("/presets/preset/name");

    foreach($result[0]->attributes() as $a => $b) {
        echo $a,'="',$b,"\"\n";
    }

?>

Вывод:

code="default"

P.S. А также попробуйте принять ответы, как упомянул @TJHeuvel; это признак того, что вы уважаете сообщество (и сообщество будет более чем счастливо помочь вам больше в следующий раз...)

person Dr.Kameleon    schedule 27.04.2012
comment
спасибо, я не понимаю, как получить значение атрибута из вашего кода. И я разместил неправильный код xml, пожалуйста, проверьте редактирование. - person guitarlass; 27.04.2012
comment
@guitarlass Что ты не понимаешь? Просто скопируйте и вставьте функцию, которую я вам отправил, и используйте ее, как я вам показал (чтобы получить определенный элемент). если вы хотите получить /presets/preset/name (= полный путь к вашему элементу), используйте его как $data = getByPattern("/presets/preset/name",$xml). Просто как тот. :-) - person Dr.Kameleon; 27.04.2012
comment
да, я это понимаю, но как я могу получить значение атрибута code? - person guitarlass; 27.04.2012
comment
@guitarlass, если у вас есть элемент, хранящийся в $data, то, чтобы получить атрибут code, просто попробуйте: $data->getAttribute("code"). - person Dr.Kameleon; 27.04.2012
comment
хорошо, спасибо, но почему мой код не работает? я закодировал $name = $pname->getAttribute('code'); - person guitarlass; 27.04.2012
comment
@guitarlass ЕСЛИ $pname это то, что вы думаете, тогда это ДОЛЖНО работать. Это не работает? Тогда $pname, скорее всего, НЕ то, что вы думаете. Проверили элемент есть? - person Dr.Kameleon; 27.04.2012
comment
даже если я использую ваш код, я все равно получаю эту ошибку Call to undefined method DOMNodeList::getAttribute() - person guitarlass; 27.04.2012
comment
@guitarlass Ладно, посмотрим. Содержит ли ваш XML-файл ТОЛЬКО то, что вы разместили в своем вопросе, или что-то еще? (если да, то сделайте репост ВСЕХ) - person Dr.Kameleon; 27.04.2012
comment
У меня есть другие блоки ‹preset›/preset› с другими значениями внутри ‹presets› ‹/presets›. а ‹icons› содержит список, разделенный запятыми. это все.. - person guitarlass; 27.04.2012
comment
спасибо, так что для этого я должен использовать get_file_contents ($ xml), чтобы принять его как строку? - person guitarlass; 27.04.2012
comment
@guitarlass, если вы хотите напрямую загрузить из пути к файлу, попробуйте: new SimpleXMLElement($filepath,0,true); вместо new SimpleXMLElement($xmlstr);. :-) - person Dr.Kameleon; 27.04.2012
comment
да работает большое спасибо. Я ненавижу работать с файловой системой. :( Я должен включить все данные в xml. Разве нет простого способа выполнить эти файлы? Например, предопределенные методы для удаления узла, поиска узла и т. д.? - person guitarlass; 27.04.2012
comment
@guitarlass Рад, что помог! (Полную справку по SimpleXMLElement см. в документации — там много примеров: php.net/manual/en/class.simplexmlelement.php). Кроме того, пожалуйста, примите ответ (это хороший способ для сообщества увидеть, что он помог). - person Dr.Kameleon; 27.04.2012
comment
как я могу удалить родительский узел ‹preset› с помощью этого ..? :) - person guitarlass; 27.04.2012
comment
@guitarlass Что ты имеешь в виду? Удалить ВСЕ узлы preset и их содержимое? - Посмотрите здесь: kavoir. com/2008/12/how-to-delete-remove-nodes-in-simplexml.html - person Dr.Kameleon; 27.04.2012
comment
не только тот, который соответствует значению атрибута, которое я проверяю. думал об использовании$result[0]->parentNode->parentNode->removeChild(?), но как я могу выбрать соответствующий «предустановленный» узел, в котором существует «код имени = по умолчанию»? - person guitarlass; 27.04.2012
comment
@guitarlass См. ссылку на мой предыдущий комментарий (я думаю, что использование unset может сработать...) - person Dr.Kameleon; 27.04.2012
comment
unset($xml –› предустановки – › предустановка); удалит все «предустановленные» узлы? - person guitarlass; 27.04.2012
comment
@guitarlass Просто укажите конкретный кивок, который вам нужен, и unset его. - person Dr.Kameleon; 27.04.2012
comment
хорошо, я еще раз подумал, но я просто не знаю, как выбрать соответствующий узел для удаления после выбора $a, который имеет соответствующее значение атрибута. я могу получить узел ‹name›, который равен $result[0], но как я могу получить родительский узел ‹name›, который является соответствующим узлом ‹preset›? - person guitarlass; 27.04.2012
comment
@guitarlass просто поиграй с xpath : $result = $xml->xpath("/presets/preset");. Кстати, XPath — это, безусловно, самый простой способ поиграть с XML — документацию можно найти здесь: w3schools.com/xpath/xpath_syntax.asp - person Dr.Kameleon; 27.04.2012
comment
Пожалуйста, отредактируйте соответствующую информацию в вопросе и / или ответе или даже опубликуйте новые ответы с новыми подробностями, если это оправдано. Раздел комментариев в вопросе/ответе предназначен только для релевантной информации, касающейся фактического сообщения, например ошибок, запросов на получение более подробной информации и т. д., а не для длительных дискуссий, даже если они могут быть полезны для вовлеченных людей. Если вам нужно продолжить это обсуждение, подумайте о том, чтобы перенести его в чат. - person Lasse V. Karlsen; 27.04.2012

На самом деле вопрос в моей голове также включает удаление узла, по ошибке я не смог его добавить. Так что, на мой взгляд, это полный ответ, я тот случай, если кто-то еще найдет это полезным. Этот ответ не включает класс SimpleXMLElement, потому что, как бы я ни старался, узел с unset() не удалялся; . Итак, вернувшись туда, где я был, я наконец нашел ответ. Это мой код. и это просто!!!

if(file_exists($xmlfile)){
              $doc = new DOMDocument();
              $doc->load($xmlfile);
              $presetgroup = $doc->getElementsByTagName( "preset" );
              foreach($presetgroup as $group){       
                 $pname = $group->getElementsByTagName( "name" );
                  $pcode = $pname->item(0)->getAttribute('code');
                 if($pcode==$preset_name){
                      echo($preset_name);
                      $group->parentNode->removeChild($group);
                 }
              }
          }
        $doc->save($xmlfile);
person guitarlass    schedule 30.04.2012