Kom ihåg mig?
Home Menu

Menu


Loopa genom DomDocument och samtidigt manipulera den

Ämnesverktyg Visningsalternativ
Oläst 2010-03-19, 19:52 #1
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
Standard Loopa genom DomDocument och samtidigt manipulera den

Hej,
Försöker traversera ett XML-dokument med hjälp av DOMDocument. Jag går igenom dokumentet och om en viss sträng finns i ett element skall detta element klonas ett antal gånger.

Säg att jag har följande XML:
Kod:
<dokument>
  <rad>
    <klona>5</klona>
    <data>
      <info>information</info>
    </data>
  </rad>
</dokument>
Den traverserar dokumentet och hittar <klona>5</klona>, då skall raden klonas 5 gånger så resultatet blir som följer:
Kod:
<dokument>
  <rad>
    <klona>1</klona>
    <data>
      <info>information</info>
    </data>
  </rad>
  <rad>
    <klona>1</klona>
    <data>
      <info>information</info>
    </data>
  </rad>
  <rad>
    <klona>1</klona>
    <data>
      <info>information</info>
    </data>
  </rad>
  <rad>
    <klona>1</klona>
    <data>
      <info>information</info>
    </data>
  </rad>
  <rad>
    <klona>1</klona>
    <data>
      <info>information</info>
    </data>
  </rad>
</dokument>
Just nu har jag använt foreach($node->childNodes...) men det funkar ju inte. Funderat på att använda while, men vet inte villkor jag skall ställa.

En annan tanke var att ha ett dokument som traverseras och ett annat där man bygger resultatet.

Använder för övrigt $node->cloneNode() och ->parentNode->insertBefore() för att skapa klonerna.
qson är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-03-20, 10:00 #2
jonny jonny är inte uppkopplad
Supermoderator
 
Reg.datum: Sep 2003
Inlägg: 6 941
jonny jonny är inte uppkopplad
Supermoderator
 
Reg.datum: Sep 2003
Inlägg: 6 941
Du kanske skulle visa upp lite av koden, så blir det lättare att se var det går snett...
jonny är inte uppkopplad   Svara med citatSvara med citat
Oläst 2010-03-20, 11:47 #3
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
qson qson är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Sep 2006
Inlägg: 513
PHP-kod:
$data = array(/* En associativ array med arrays av massa stdclass-objekt */);
$firstCol false;
$firstRow true;
function 
handleNode(&$node,$data=null) {

    global 
$firstRow,$firstCol,$data;
    
    switch(
$node->nodeType) {
        case 
XML_ELEMENT_NODE
            {
            
                switch(
$node->tagName) {
                    case 
'table:table-row':
                    
                        
$formula $node->firstChild;
                        
$m = array();
                            if (
preg_match('/^for\s?each\s*\(\s*\$([a-z0-9_]+)\s+as\s+\$([a-z0-9_]+)\s*\)\s*(\{)?/i',$formula->textContent,$m))
                            {
                                
$array $m[1];
                                
$iterator $m[2];
                                
                                if (
array_key_exists($array,$data)) {
                                    
                                    foreach (
$data[$array] as $row) {
                                    
                                        
$newNode $node->cloneNode();
                                    
                                        foreach (
$newNode->childNodes as $childNode)
                                            
handleNode($childNode,$row);
                                    
                                        
$node->insertBefore($newNode,$node->nextSibling);
                                        
                                    }
                                    
                                    
$node->parentNode->removeChild($node);
                                }
                                else {
                                    
$node->parentNode->removeChild($node);
                                    return;
                                }
                            }
                        
                        
$firstCol true;
                        break;
                    case 
'table:table-cell':
                        if (!
$firstCol) {
                            
$m = array();
                            if (
preg_match('/^\$([a-z0-9_]+)\s*->\s*\$([a-z0-9_]+)/i',$node->textContent,$m))
                            {
                                
$node->textContent preg_replace('/^\$([a-z0-9_]+)\s*->\s*\$([a-z0-9_]+)/ie','@$data->\\2');
                            }
                        }
                        break;
                }
                echo 
$node->tagName."\n";
                foreach (
$node->childNodes as $childNode)
                    
handleNode($childNode);
                    
                    
                    
                    
                switch(
$node->tagName) {
                    case 
'table:table-row':
                        
$firstRow false;
                        break;
                    case 
'table:table-cell':
                        
$firstCol=false;
                        break;
                }
            }
            break;
        case 
XML_TEXT_NODE:
            echo 
"\"$node->textContent\"\n";
            break;
    }


Min XML ser egentligen ut så här (bara det viktigaste):
Kod:
...
        <table:table-row>
          <table:table-cell>
            <text:p>foreach ($receipts as $receipt) {</text:p>
          </table:table-cell>
          <table:table-cell>
            <text:p>$receipt-&gt;id</text:p>
          </table:table-cell>
          <table:table-cell>
            <text:p>$receipt-&gt;name</text:p>
          </table:table-cell>
          <table:table-cell>
            <text:p>$receipt-&gt;amount</text:p>
          </table:table-cell>
          <table:table-cell>
            <text:p>$receipt-&gt;vat1</text:p>
          </table:table-cell>
          <table:table-cell>
            <text:p>$receipt-&gt;vat2</text:p>
          </table:table-cell>
          <table:table-cell>
            <text:p>$receipt-&gt;vat3</text:p>
          </table:table-cell>
          <table:table-cell>
            <text:p>$receipt-&gt;net</text:p>
          </table:table-cell>
          <table:table-cell>
            <text:p>$receipt-&gt;date</text:p>
          </table:table-cell>
          <table:table-cell/>
        </table:table-row>
...mer XML...
Notera foreach som står i första cellen, den matchas i en preg_match, och sedan klonas raden lika många gånger som det finns värden i arrayen.
Jag tror att problemet ligger i foreach ($node->childNodes) eftersom den tar en ögonblicksbild av barnen och loopar dem, och tar inte hänsyn till ändringar.

Hur kan man tänka på annat sätt?
qson är inte uppkopplad   Svara med citatSvara med citat
Svara


Aktiva användare som för närvarande tittar på det här ämnet: 1 (0 medlemmar och 1 gäster)
 

Regler för att posta
Du får inte posta nya ämnen
Du får inte posta svar
Du får inte posta bifogade filer
Du får inte redigera dina inlägg

BB-kod är
Smilies är
[IMG]-kod är
HTML-kod är av

Forumhopp


Alla tider är GMT +2. Klockan är nu 06:14.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson
 
Copyright © 2017