1

PHPを使用してXMLでノードの名前を変更する方法を見つけようとしていますか?

私はここまで来ました:

$dom = new DOMDocument( '1.0' );
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;

// load the xml file
$dom->loadXML( '<?xml version="1.0" encoding="ISO-8859-1"?>
<library>
  <data>
    <invite>
      <username>jmansa</username>
      <userid>1</userid>
    </invite>
    <update>1</update>
  </data>
</library>', LIBXML_NOBLANKS );
$xpath = new DOMXPath($dom);

//find all 'data' nodes.
$node = $xpath->query("//data");

// if found
if( $node->length ) {
    foreach ($node as $n) {
       // RENAME HERE? //
    }
}

echo "<xmp>". $dom->saveXML() ."</xmp>";

<data>今、私はに名前を変更したいと思い<invites>ます。これを行うことができますか? はいの場合、その方法は?

4

2 に答える 2

1

Node::nodeName プロパティが read-only であるため、ノードの名前 (それぞれ「data」または「invites」) を DOM 経由で名前変更することはできません。

「invites」という名前の新しいノードを作成し、それを「data」ノードの前に追加し、「data」の子を新しい「invites」ノードに移動し、「data」ノードを削除してから、ツリーを出力して結果。

例:

<?php
// Create a test document.
    $dom = new DOMDocument( '1.0' );
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;

// Load the xml file.
    $dom->loadXML('<?xml version="1.0" encoding="ISO-8859-1"?'.'>
    <library>
      <data attr1="1" attr2="2">
        <invite>
          <username>jmansa</username>
          <userid>1</userid>
        </invite>
        <update>1</update>
      </data>
    </library>', LIBXML_NOBLANKS );
    $xpath = new DOMXPath($dom);

    // Convert <data> to <invites>.
    if ($dataNode = $xpath->query("/library/data")->item(0))
    {
    // Create the <invites> node.
        $invitesNode = $dom->createElement('invites');
        $dataAttrs   = $dataNode->attributes;
        foreach ($dataAttrs as $dataAttr)
        {   $invitesNode->setAttributeNodeNS($dataAttr->cloneNode());   }
        $dom->documentElement->appendChild($invitesNode);

    // Move the <data> children over.
        if ($childNodes = $xpath->query("/library/data/*"))
        {
            foreach ($childNodes as $childNode)
            {   $invitesNode->appendChild($childNode);  }
        }

    // Remove <data>.
        $dataNode->parentNode->removeChild($dataNode);
    }

// Test the result.
    echo $dom->saveXML();
?>
于 2012-09-17T16:39:24.813 に答える
0

拡張テストケースを使用した私のソリューション:

// Changes the name of element $element to $newName.
function renameElement($element, $newName) {
  $newElement = $element->ownerDocument->createElement($newName);
  $parentElement = $element->parentNode;
  $parentElement->insertBefore($newElement, $element);

  $childNodes = $element->childNodes;
  while ($childNodes->length > 0) {
    $newElement->appendChild($childNodes->item(0));
  }

  $attributes = $element->attributes;
  while ($attributes->length > 0) {
    $attribute = $attributes->item(0);
    if (!is_null($attribute->namespaceURI)) {
      $newElement->setAttributeNS('http://www.w3.org/2000/xmlns/',
                                  'xmlns:'.$attribute->prefix,
                                  $attribute->namespaceURI);
    }
    $newElement->setAttributeNode($attribute);
  }

  $parentElement->removeChild($element);
}

function prettyPrint($d) {
  $d->formatOutput = true;
  echo '<pre>'.htmlspecialchars($d->saveXML()).'</pre>';
}

$d = new DOMDocument( '1.0' );
$d->loadXML('<?xml version="1.0"?>
<library>
  <data a:foo="1" x="bar" xmlns:a="http://example.com/a">
    <invite>
      <username>jmansa</username>
      <userid>1</userid>
    </invite>
    <update>1</update>
  </data>
</library>');

$xpath = new DOMXPath($d);
$elements = $xpath->query('/library/data');
if ($elements->length == 1) {
  $element = $elements->item(0);
  renameElement($element, 'invites');
}

prettyPrint($d);

ところで、このソリューションを.NET の PHP ドキュメントにコメントDOMElementとして追加しました。

于 2013-02-26T15:06:01.207 に答える