ほとんどの回答に役立ちます願っています。 インデントジョブを実行するためにdom機能を使用するもう1つの方法があります。 loadXML()domメソッドは、xmlソースにあるインデント文字をテキストノードとしてインポートします。そのようなテキストノードをdomから削除し、正しくフォーマットされたテキストノードを再作成することです(詳細については、以下のコードのコメントを参照してください)。
xmlIndent()関数は、domDocumentから継承されたindentDomDocumentクラスのメソッドとして実装されています。ただ明らかに、ルートXML要素は、テキストの子を含んでいない可能性があることが分かった
$dom = new indentDomDocument("1.0");
$xml = file_get_contents("books.xml");
$dom->loadXML($xml);
$dom->xmlIndent();
echo $dom->saveXML();
class indentDomDocument extends domDocument {
public function xmlIndent() {
// Retrieve all text nodes using XPath
$x = new DOMXPath($this);
$nodeList = $x->query("//text()");
foreach($nodeList as $node) {
// 1. "Trim" each text node by removing its leading and trailing spaces and newlines.
$node->nodeValue = preg_replace("/^[\s\r\n]+/", "", $node->nodeValue);
$node->nodeValue = preg_replace("/[\s\r\n]+$/", "", $node->nodeValue);
// 2. Resulting text node may have become "empty" (zero length nodeValue) after trim. If so, remove it from the dom.
if(strlen($node->nodeValue) == 0) $node->parentNode->removeChild($node);
}
// 3. Starting from root (documentElement), recursively indent each node.
$this->xmlIndentRecursive($this->documentElement, 0);
} // end function xmlIndent
private function xmlIndentRecursive($currentNode, $depth) {
$indentCurrent = true;
if(($currentNode->nodeType == XML_TEXT_NODE) && ($currentNode->parentNode->childNodes->length == 1)) {
// A text node being the unique child of its parent will not be indented.
// In this special case, we must tell the parent node not to indent its closing tag.
$indentCurrent = false;
}
if($indentCurrent && $depth > 0) {
// Indenting a node consists of inserting before it a new text node
// containing a newline followed by a number of tabs corresponding
// to the node depth.
$textNode = $this->createTextNode("\n" . str_repeat("\t", $depth));
$currentNode->parentNode->insertBefore($textNode, $currentNode);
}
if($currentNode->childNodes) {
$indentClosingTag = false;
foreach($currentNode->childNodes as $childNode) $indentClosingTag = $this->xmlIndentRecursive($childNode, $depth+1);
if($indentClosingTag) {
// If children have been indented, then the closing tag
// of the current node must also be indented.
$textNode = $this->createTextNode("\n" . str_repeat("\t", $depth));
$currentNode->appendChild($textNode);
}
}
return $indentCurrent;
} // end function xmlIndentRecursive
} // end class indentDomDocument
私は質問が何であるか分かりません。あなたが表示するコードはあなたが求めている出力を与えます。証明:http://codepad.org/4UGyRspxとhttp://codepad.org/bLTOFQrp - あなたはインデントレベルについて質問していますか?使用されるスペースの数? – Gordon
正規表現に基づく素直な関数があります:[PHPを使ったXML形式](http://recurser.com/articles/2007/04/05/format-xml-with-php/) – Tomalak
関連する長いインデントが心配です:[preg_replace(コールバックなし)で字下げを変換](0120-919-066)。 – hakre