Сущность XML в setAttribute / addAttribute - PullRequest
4 голосов
/ 23 ноября 2011

Хорошо, возможно, я упускаю что-то простое. Я долго искал и не повезло. Мне нужно вставить сущность в атрибут XML. Для этого мне нужно иметь возможность использовать амперсанд (&) в сочетании с методом setAttribute для класса DOM (или addAttribute для класса simpleXML). Когда я пытаюсь его использовать, он выходит за пределы амперсанда, поэтому &entity; становится &entity;. Попытка вручную убрать амперсанд \&entity; просто приводит к \&entity;. Выводим амперсандную сущность &entity; просто удваиваем ее &entity;. Я понимаю, почему это происходит, амперсанды нарушают XML, если не связаны с действительным объектом. Проблема в том, что он связан с сущностью, и я не могу понять, как его использовать.

Я нашел методы createEntityReference и DOMEntityReference , но документация для этих методов плохая, и я не уверен, что это то, что мне нужно. Похоже, что поиск этих терминов приводит к появлению одной и той же документации PHP, но с разных сайтов. Я пытался искать эту проблему отдельно, но я просто получаю результаты, объясняющие то, что я уже знаю и указал выше. Я пробовал и DOM и SimpleXML, но оба дают одинаковые результаты. Я просто слишком усложняю или это действительно не поддерживается?

1 Ответ

2 голосов
/ 23 ноября 2011

Честно говоря, для меня это был сложный вопрос, поскольку я сам не думал об этом, хотя ответ довольно прост:

Согласно четному Уровню 1 рекомендации DOM интерфейс Attr наследует интерфейс Node, то есть вы можете добавлять узлы к атрибуту. И EntityReference допускается у Attr детей.

В XML, где значение атрибута может содержать ссылки на сущности, дочерние узлы узла Attr предоставляют представление, в котором ссылки на сущности не раскрываются. Эти дочерние узлы могут быть узлами Text или EntityReference. Поскольку тип атрибута может быть неизвестен, значения атрибутов с токенами отсутствуют.

Вот рабочий пример в PHP:

<?php

// a valid XML should contain used entities declarations to be valid,
// but DOM recs do not contain means to generate DTD;
// in PHP you can use XMLWriter for the purpose though 
$dtd = <<<DTD
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
  <!ENTITY my_entity "some content">
]>
<root/>
DTD;

$xml = new DOMDocument();
$xml->formatOutput = true;

$xml->loadXML($dtd);

$root = $xml->documentElement;

$entity = $xml->createEntityReference( 'my_entity' );

$an_attr = $xml->createAttribute( 'attr' );
$an_attr->appendChild( $xml->createTextNode('prefix ') );
$an_attr->appendChild( $entity );
$an_attr->appendChild( $xml->createTextNode(' suffix') );
$root->setAttributeNode( $an_attr );

// clone the entity to use it more than once
$root->appendChild( $entity->cloneNode() );

print $xml->saveXML();

?>

, что приводит к

C:\>\php\5.3.8\php.exe entities.php
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE root [
<!ENTITY my_entity "some content">
]>
<root attr="prefix &my_entity; suffix">&my_entity;</root>
...