5

私が試したこととうまくいかないこと:

  • 入力:

    $d = new DOMDocument();
    $d->formatOutput = true;
    
    // Out of my control:
    $someEl = $d->createElementNS('http://example.com/a', 'a:some');
    
    // Under my control:
    $envelopeEl = $d->createElementNS('http://example.com/default',
                                      'envelope');
    $d->appendChild($envelopeEl);
    $envelopeEl->appendChild($someEl);
    
    echo $d->saveXML();
    
    $someEl->prefix = null;
    echo $d->saveXML();
    
  • 置換後の出力は無効な XML です:

    <?xml version="1.0"?>
    <envelope xmlns="http://example.com/default">
      <a:some xmlns:a="http://example.com/a"/>
    </envelope>
    <?xml version="1.0"?>
    <envelope xmlns="http://example.com/default">
      <:some xmlns:a="http://example.com/a" xmlns:="http://example.com/a"/>
    </envelope>
    

子がいる可能性があることに注意してください<a:some>。1 つの解決策は、新しい を作成し、すべての子を からに<some>コピーすることです。それは行く方法ですか?<a:some><some>

4

1 に答える 1

3

これは本当に興味深い質問です。私の最初の意図は、<a:some>ノードのクローンを作成し、xmlns:a属性を削除し<a:some>、クローンを削除して挿入することでした - <a>。ただし、PHP では、通常の属性のように xmlns:a 属性を削除できないため、これは機能しません。

PHP の DOM メソッドに苦労した後、私は問題をグーグルで検索し始めました。これに関するPHPドキュメントでこのコメントを見つけました。ユーザーは、名前空間なしでノードを手動で複製する関数を作成することを提案します。

<?php

/**
 * This function is based on a comment to the PHP documentation.
 * See: http://www.php.net/manual/de/domnode.clonenode.php#90559
 */
function cloneNode($node, $doc){
  $unprefixedName = preg_replace('/.*:/', '', $node->nodeName);
  $nd = $doc->createElement($unprefixedName);

  foreach ($node->attributes as $value)
    $nd->setAttribute($value->nodeName, $value->value);

  if (!$node->childNodes)
    return $nd;

  foreach($node->childNodes as $child) {
    if($child->nodeName == "#text")
      $nd->appendChild($doc->createTextNode($child->nodeValue));
    else
      $nd->appendChild(cloneNode($child, $doc));
  }

  return $nd;
}

これを使用すると、次のようなコードになります。

$xml = '<?xml version="1.0"?>
<envelope xmlns="http://example.com/default">
  <a:some xmlns:a="http://example.com/a"/>
</envelope>';

$doc = new DOMDocument();
$doc->loadXML($xml);

$elements = $doc->getElementsByTagNameNS('http://example.com/a', 'some');
$original = $elements->item(0);

$clone = cloneNode($original, $doc);
$doc->documentElement->replaceChild($clone, $original);

$doc->formatOutput = TRUE;
echo $doc->saveXML();
于 2013-02-22T17:17:13.553 に答える