3

DOMDocument::importNodeメソッドを使用して、他のドキュメント要素からノードのツリーをインポートすることはよく知っています。

ただし、私が疑問に思っていたのは、ノードをインポートするときにノードのツリーの名前空間プレフィックスを自動的に変更できるかどうか、つまり、その名前空間のすべてのノードに新しいプレフィックスを指定できるかどうかです。

既存のドキュメントでは、すべてのノードに「name」、「identity」などの名前が付いているとします。それらを新しいドキュメントにインポートすると、他の名前空間と一緒になるので、「nicnames:name」、「nicnames:identity」などとして表示されるようにしたいと思います。このプレフィックスをプログラムで変更できるようにして、別のコンテキストで、インポート先のドキュメントに応じて、たとえば「myprefix:name」、「myprefix:identity」としてインポートできるようにしたいと考えています。

編集:私の回答の説明によると、実際にこれを行う必要はないことがわかりました。XML の名前空間を誤解していました。

4

2 に答える 2

0

XML 名前空間を誤解していたことに気付きました。彼らは実際には私が思っていたよりもはるかに優れています。

私は、1 つのドキュメントで使用される XML 名前空間ごとに、異なる名前空間プレフィックスを付ける必要があると考えていました。本当じゃない。

必要に応じて xmlns 属性を含めるだけで、名前空間プレフィックスがなくても、ドキュメント全体でさまざまな名前空間を使用できます。その xmlns 属性は、その要素とその子孫に対してのみ効果があり、そのプレフィックスの名前空間をオーバーライドします。木。

たとえば、ある名前空間を別の名前空間に含めるために、次のことを行う必要はありません。

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

あなたはただすることができます

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

名前空間プレフィックスは、特定の状況では適切なショートカットですが、別の名前空間の別のドキュメント内に 1 つのドキュメントを含めるだけの場合は必要ありません。

于 2010-04-10T02:39:48.213 に答える
0

その場合、おそらく独自のインポート コードを作成する必要があります。例えば

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>
于 2010-04-07T08:14:35.560 に答える