2011-04-25 10 views
11

Próbuję nauczyć się XML i wiem, że to jest problem z nieprawidłowym importowaniem węzłów. Ale nie mogę tego rozgryźć. Rozglądam się i większość ludzi nie ma wielu elementów podrzędnych, tak jak to robię w działach.XML XML DOM Uncaught wyjątek "DOMException" z komunikatem "Wrong Document Error"

Oto moja struktura 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> 

Rozumiem, że SOT jest mój element główny i że odpowiednie jednostki są „dziećmi” SOT i każdy wydział ma wiele pracownika „dzieci”. Problem, który napotykam, polega na tym, że próbuję dodać nowego pracownika do określonego działu. Kiedy próbuję $departmentArray->item($i)->appendChild($employee);, otrzymuję błąd nieprawidłowego dokumentu.

Używam tego kodu PHP aby spróbować dołączyć dziecko do 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"); 


?> 

Każda pomoc wyjaśniając, jak prawidłowo zaimportować wszystkie węzły towarowe, aby móc dołączyć na nich będzie bardzo mile widziane. Próbowałem używać tablic.

Odpowiedz

16

trzeba importować każdy węzeł, aby dołączyć go do inny dokument:

$departmentArray->item($i)->appendChild($doc->importNode($employee, true)); 
+0

Czy to dlatego, że departmentArray jest obecnie wewnątrz oryginalnego dokumentu, a nie $ $ newDoc? Dzięki za pomoc! – Grant

+0

Tak, to jest powód. – SteAp

+0

Ważny jest drugi parametr metody importNode. Domyślnie jest to wartość false i nie importuje elementów potomnych. – jenkin90

9

Jestem prawie pewien, że tak się dzieje, ponieważ próbujesz dołączyć element z innego dokumentu do dokumentu wyjściowego.

Znalazłem ten kod in a comment na stronie php dla DOMNode::cloneNode, który może być tym, co chcesz.

<?php 
    $dom1->documentElement->appendChild( 
     $dom1->importNode($dom2->documentElement, true) 
    ); 
?> 

Alternatywnie, można spojrzeć na eksporcie XML węzła i ponownego importowania go w DOMDocumentFragment, ale będę musiał eksperymentować, aby wiedzieć na pewno.

Powiązane problemy