DOM: как импортировать узлы и дать им другой префикс пространства имен - PullRequest
3 голосов
/ 07 апреля 2010

Я знаком с методом DOMDocument :: importNode для импорта дерева узлов из какого-либо другого элемента документа.

Однако мне было интересно, могу ли я автоматически изменять префикс пространства имен в дереве узлов при импорте, то есть задавать новый префикс для всех узлов этого пространства имен.

Скажем, в их существующем документе все узлы имеют такие имена, как "имя", "личность" и т. Д. При импорте их в мой новый документ они будут располагаться рядом с другими пространствами имен, поэтому я бы хотел, чтобы они отображались как «ники: имя», «ники: имя» и так далее. Я хотел бы иметь возможность изменять этот префикс программно, чтобы в другом контексте я мог импортировать их как, например, «myprefix: name», «myprefix: identity» в зависимости от документа, в который они импортированы.

Редактировать: согласно объяснению в моем ответе, я понял, что на самом деле мне не нужно это делать. Я неправильно понял пространства имен в XML.

Ответы [ 2 ]

0 голосов
/ 10 апреля 2010

Я обнаружил, что неправильно понял пространства имен XML.На самом деле они намного лучше, чем я думал.

Я думал, что каждое пространство имен XML, используемое в одном документе, должно иметь свой префикс пространства имен.Это не так.

Вы можете использовать разные пространства имен по всему документу даже без префиксов пространства имен, просто включив атрибут xmlns, где это уместно, и этот атрибут xmlns действует только для этого элемента и его потомков, переопределяя пространство имендля того префикса, который мог быть установлен выше дерева.

Например, чтобы иметь одно пространство имен внутри другого, вам не нужно делать:

<record xmlns="namespace1">
  <person:surname xmlns:person="namespace2">Smith</person:surname>
</record>

Вы можете просто сделать

<record xmlns="namespace1">
  <surname xmlns="namespace2">Smith</person>
</record>

Префиксы пространства имен - это хороший ярлык в определенных ситуациях, но не обязательный, если просто включить один документ в другой из другого пространства имен.

0 голосов
/ 07 апреля 2010

Возможно, вам придется написать свой собственный код импорта. Э.Г.

function importNS(DOMNode $target, DOMNode $source, $fnImportElement, $fnImportAttribute) {
  switch($source->nodeType) {
    case XML_ELEMENT_NODE:
      // invoke the callback that creates the new DOMElement node
      $newNode = $fnImportElement($target->ownerDocument, $source);
      if ( !is_null($newNode) && !is_null($source->attributes) ) {
        foreach( $source->attributes as $attr) {
          importNS($newNode, $attr, $fnImportElement, $fnImportAttribute);
        }
      }
      break;
    case XML_ATTRIBUTE_NODE:
      // invoke the callback that creates the new DOMAttribute node
      $newNode = $fnImportAttribute($target->ownerDocument, $source);
      break;
    default:
      // flat copy
      $newNode = $target->ownerDocument->importNode($source);
  }

  if ( !is_null($newNode) ) {
    // import all child nodes
    if ( !is_null($source->childNodes) ) {
      foreach( $source->childNodes as $c) {
        importNS($newNode, $c, $fnImportElement, $fnImportAttribute);
      }
    }
    $target->appendChild($newNode);
  }
}

$target = new DOMDocument;
$target->loadxml('<foo xmlns:myprefix="myprefixUri"></foo>');

$source = new DOMDocument;
$source->loadxml('<a>
  <b x="123">...</b>
</a>');

$fnImportElement = function(DOMDocument $newOwnerDoc, DOMElement $e) {
  return $newOwnerDoc->createElement('myprefix:'.$e->localName);
};

$fnImportAttribute = function(DOMDocument $newOwnerDoc, DOMAttr $a) {
  // could use namespace here, too....
  return $newOwnerDoc->createAttribute($a->name);
};

importNS($target->documentElement, $source->documentElement, $fnImportElement, $fnImportAttribute);
echo $target->savexml();

печать

<?xml version="1.0"?>
<foo xmlns:myprefix="myprefixUri"><myprefix:a>
  <myprefix:b x="123">...</myprefix:b>
</myprefix:a></foo>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...