#php #xml #dom #xmldom
#php #xml #dom #xmldom
Вопрос:
Я пытаюсь изучить XML, и я знаю, что это проблема с неправильным импортом узлов. Но я не могу в этом разобраться. Я осмотрелся, и у большинства людей нет нескольких дочерних элементов, как у меня с departments.
Вот моя структура XML:
<SOT>
<DEPARTMENT name="Aviation Technology" id="AT">
<EMPLOYEE type="Faculty">
<LOGIN>jdoe1</LOGIN>
<NAME>John Doe</NAME>
</EMPLOYEE>
<EMPLOYEE type="Faculty">
<LOGIN>jdoe2</LOGIN>
<NAME>Jane Doe</NAME>
</EMPLOYEE>
<EMPLOYEE type="Faculty">
<LOGIN>jdoe3</LOGIN>
<NAME>Joe Doe</NAME>
</EMPLOYEE>
</DEPARTMENT>
<DEPARTMENT name="Building and Construction Management" id="BCM">
</DEPARTMENT>
<DEPARTMENT name="Computer Graphics Technology" id="CGT">
</DEPARTMENT>
</SOT>
Я понимаю, что SOT является моим корневым элементом и что отделы являются «дочерними элементами» SOT, и в каждом отделе есть несколько «дочерних элементов» сотрудников. Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь добавить нового сотрудника в определенный отдел. При попытке $departmentArray->item($i)->appendChild($employee);
я получаю ошибку неправильного документа.
Я использую этот PHP-код, чтобы попытаться добавить дочерний элемент в departmentNode
<?php
//grab form data
$username = $_POST['username'];
$employeeName = $_POST['employeeName'];
$department = $_POST['department'];
//create new DOMDocument to hold current XML data
$doc = new DOMDocument();
$doc->load("test.xml");
$xpath = new DOMXpath($doc);
//create our new DOMDocument for combining the XML data
$newDoc = new DOMDocument();
$newDoc->preserveWhiteSpace = false;
//create School of Tech Node and append to new doc
$sotElement = $newDoc->createElement("SOT");
$newDoc->appendChild($sotElement);
$root = $newDoc->documentElement;
//grab the department Nodes
$departmentArray = $doc->getElementsByTagName("DEPARTMENT");
//create a new employee and set attribute to faculty
$employee = $newDoc->createElement("EMPLOYEE");
$employee->setAttribute("type", "Faculty");
//counters (might use them later for ->item(counter) function
$indexCounter = 0;
$i = 0;
foreach($departmentArray as $departmentNode){
if(strcmp($departmentNode->getAttribute('name'),$department) == 0){//check if departments match
//create login element
$loginNode = $newDoc->createElement("LOGIN");
$loginNode->appendChild($newDoc->createTextNode($username));
$employee->appendChild($loginNode);
//create name node
$nameNode = $newDoc->createElement("NAME");
$nameNode->appendChild($newDoc->createTextNode($employeeName));
$employee->appendChild($nameNode);
//append employee onto department node
//$departmentArray->item($i) = $doc->importNode($departmentArray->item($i), true);
$departmentArray->item($i)->appendChild($employee);
//set index of department array (possibly used for appending later)
$indexCounter = $i;
}
$i ;
}
#######################################
/*Write out data to XML file */
#######################################
//$departmentArray = $doc->getElementsByTagName("DEPARTMENT");
foreach($departmentArray as $departmentNode){
$tempNode = $newDoc->importNode($departmentNode, true);
/*if(strcmp($departmentNode->getAttribute('name'),$department) == 0){
$sotElement->appendChild($employee);
}*/
$sotElement->appendChild($tempNode);
}
$newDoc->formatOutput = true;
$newDoc->save("test2.xml");
?>
Была бы высоко оценена любая помощь, объясняющая, как правильно импортировать все узлы отдела, чтобы иметь возможность добавлять к ним. Я пробовал использовать массивы.
Ответ №1:
Вам нужно импортировать любой узел, чтобы добавить его в другой документ:
$departmentArray->item($i)->appendChild( $doc->importNode( $employee, true ) );
Комментарии:
1. Это потому, что departmentArray в настоящее время находится внутри исходного $ doc, а не $ newDoc? Спасибо за помощь!
2. Важен второй параметр importNode. По умолчанию имеет значение false и не импортирует дочерние элементы.
Ответ №2:
Я почти уверен, что это происходит из-за того, что вы пытаетесь добавить элемент из другого документа в свой выходной документ.
Я нашел этот код в комментарии на сайте php для DOMNode::cloneNode
, который может быть тем, что вам нужно.
<?php
$dom1->documentElement->appendChild(
$dom1->importNode( $dom2->documentElement, true )
);
?>
В качестве альтернативы, вы могли бы посмотреть на экспорт XML узла и повторно импортировать его в DOMDocumentFragment
, но мне пришлось бы поэкспериментировать, чтобы узнать наверняка.