Найдите, существует ли элемент в XML, используя PHP DOM - PullRequest
0 голосов
/ 07 мая 2020

У меня есть элемент dom, из которого я хочу найти, существует ли указанный c подэлемент.

Мой узел выглядит так:

    <properties>
        <property name="a-random-neme" option="option2" >value1</property>
        <property name="another-random-name">V2</property>
        <property name="yet-another-random-name" option="option5" >K3</property>
    </properties>

в php на него ссылается объект dom

$properties_node;

В другой части кода php я хочу проверить, существуют ли данные, которые я собираюсь добавить,

    $datum = [ 'name'=>'yet-another-random-name', 'value'=>'K3'];
    //NOTE: If other attributes exists I want to keep them
    $prop=$dom->createElement('property',$datum['value']);
    $prop->setAttribute('name', $datum['name']);

    if(prop_list_contains($properties-node,$prop,['name']))
        $properties_node->appendChild($prop);
    else
        echo "not adding element, found\n";

теперь я хочу сделать

    /**
     @param $properties_node reference to the existing dom object
     @param $prop the new element I want to add
     @param $required_matches an array containing the name of the attributes that must match

     @return matching element if match is found, false otherweise 
    */
    function prop_list_contains(&$properties_node,$prop,array $required_matches){
    // here I have no Idea how to parse the document I have

      return false
    }

Desiderata:

not adding element, found

1 Ответ

1 голос
/ 07 мая 2020

Самый простой способ, который я могу подумать, если использовать XPath для проверки, существует ли уже узел.

Предполагая, что вы будете использовать только 1 элемент для сопоставления (возможно больше, но намного сложнее). Сначала извлекается значение из нового узла, а затем используется XPath, чтобы проверить, существует ли уже совпадающее значение в текущих данных.

Главное в этом процессе - убедиться, что вы используете правильный контекст для поиска. По сути, это то, что нужно для поиска: сначала используется новый элемент, а затем текущий, чтобы проверить его.

function prop_list_contains(DOMXPath $xp, $properties_node, $prop, 
        array $required_matches){
    // Extract value from new node
    $compare = $xp->evaluate('string(@'.$required_matches[0].')', $prop);
    // Check for the value in the existing data
    $xpath = 'boolean(./property[@'. $required_matches[0] . ' = "' . $compare . '"])';

    return ( $xp->evaluate($xpath, $properties_node) );
}

Это также означает, что вам нужно создать объект XPath для передачи ...

$xp = new DOMXPath($dom);

это сохраняет его создание каждый раз.

Также, поскольку это возвращает true, если узел существует, вам нужно изменить свой тест, чтобы использовать ! ...

if( ! prop_list_contains($xp, $properties_node,$prop,['name'])) {
    $properties_node->appendChild($prop);
}
else    {
    echo "not adding element, found\n";
}
...