Вставка новой строки с использованием DOM - PullRequest
3 голосов
/ 16 сентября 2011

Я пытаюсь вставить новый узел в документ XML. Я использую simpleXML для большей части анализа, но для этой части мне нужно использовать DOM. Это функция, которую я использую для добавления

function simplexml_insert_after(SimpleXMLElement $sxe, SimpleXMLElement $insert, SimpleXMLElement $target)   
 {
    $target_dom = dom_import_simplexml($target);
    $target_dom->formatOutput = true;
    $target_dom->preserveWhiteSpace = false;
    $insert_dom = $target_dom->ownerDocument->importNode(dom_import_simplexml($insert), true);
    if ($target_dom->nextSibling) {
        return $target_dom->parentNode->insertBefore($insert_dom, $target_dom->nextSibling);
    } else {
        return $target_dom->parentNode->appendChild($insert_dom);
    }
}

И называя это так:

$meta2 = new SimpleXMLElement("<meta/>");
$meta2->addAttribute('name', 'subject');
$meta2->addAttribute('value', $doc_id); 
$target = current($my_xml->xpath('//meta[last()]'));
simplexml_insert_after($my_xml, $meta2, $target);

Моя проблема в том, что он вставляет новый узел сразу после цели, а не в новую строку, поэтому результирующий XML выглядит так:

<meta content="a" name="ap-category"/>
<meta content="bx" name="ap-format"/><meta name="subject" value="urn:blah"/>

Когда я бы хотел, чтобы это выглядело так:

<meta content="a" name="ap-category"/>
<meta content="bx" name="ap-format"/>
<meta name="subject" value="urn:blah"/>

Я пытался изменить preserveWhiteSpace на true, но это не помогло. Как мне добавить новую строку перед вставкой этого узла?

редактировать Вот исправление, которое сработало:

 function simplexml_insert_after(SimpleXMLElement $sxe, SimpleXMLElement $insert,SimpleXMLElement $target)   
 {
     $target_dom = dom_import_simplexml($target);
     $target_dom->formatOutput = true;
     $target_dom->preserveWhiteSpace = false;
     $insert_dom = $target_dom->ownerDocument->importNode(dom_import_simplexml($insert), true);
     if ($target_dom->nextSibling) {
          $result = $target_dom->parentNode->insertBefore($insert_dom, $target_dom->nextSibling);
          $target_dom->parentNode->insertBefore($target_dom->ownerDocument->createTextNode("\n"), $result);
          return $result
     } else {
          return $target_dom->parentNode->appendChild($insert_dom);
     }
}

Ответы [ 2 ]

4 голосов
/ 16 сентября 2011

Попробуйте вставить текстовый узел непосредственно перед элементом, который вы хотите вставить, что-то вроде этого:

function simplexml_insert_after(SimpleXMLElement $sxe, 
                                SimpleXMLElement $insert, 
                                SimpleXMLElement $target)   
{
    $target_dom = dom_import_simplexml($target);
    $target_dom->formatOutput = true;
    $target_dom->preserveWhiteSpace = false;

    $document = $target_dom->ownerDocument;
    $insert_dom = $document->importNode(dom_import_simplexml($insert), true);

    $parentNode = $target_dom->parentNode;
    if ($target_dom->nextSibling) {
        $result = $parentNode->insertBefore($insert_dom, $target_dom->nextSibling);
        $parentNode->insertBefore($document->createTextNode("\n"), $result);
        return $result
    } else {
        return $parentNode->appendChild($insert_dom);
    }
}
0 голосов
/ 16 сентября 2011

Попробуйте изменить вызов метода следующим образом:

simplexml_insert_after($my_xml, "\n" . $meta2, $target);

... с preserveWhiteSpace = true;

...