1

I have an XML file which contains family tree data in a nested structure, and I'm wanting to parse it into a nested list.

I have the following code

<?php 
    $doc = new DOMDocument();
    $doc->load('armstrong.xml');
    echo $doc->saveXML();
?>

Which loads in the following XML file and prints it as-is

<?xml version="1.0" encoding="UTF-8"?>
<indi>
    <id>id1</id>
    <fn>Matt</fn>
    <bday>1919</bday>
    <dday>2000</dday>
    <spouse>Evelyn Ross</spouse>
    <family>
        <indi>
        <id>id2</id>
        <fn>Jane</fn>
        <bday></bday>
        <dday></dday>
        <spouse></spouse>
        <family>

        </family>
    </indi>
    <indi>
        <id>id3</id>
        <fn>Jason</fn>
        <bday></bday>
        <dday></dday>
        <spouse></spouse>
        <family>

        </family>
    </indi>
    <indi>
        <id>id4</id>
        <fn>Samuel</fn>
        <bday></bday>
        <dday></dday>
        <spouse></spouse>
        <family>
            <indi>
                <id>id5</id>
                <fn>John</fn>
                <bday></bday>
                <dday></dday>
                <spouse></spouse>
                <family>

                </family>
            </indi>
            <indi>
                <id>id6</id>
                <fn>John</fn>
                <bday></bday>
                <dday></dday>
                <spouse></spouse>
                <family>

                </family>
            </indi>
        </family>
    </indi>
</family>

However I want to parse it into the following format:

<ul>
   <li> 
    <span class="vcard person" id="id1">
            <span class="edit fn">Matt</span> 
        <span class="edit bday">1956</span> 
        <span class="edit dday"></span>
            <span class="edit spouse">Eunace Fulton</span>
        </span> 
    <ul> ... List of Family ... </ul>
   </li>
</ul>

I'm pretty new to php, so if this is an incredibly simple problem I apologise! Would really appreciate any ideas.

EDIT

I'm now using the following recursive loop but still having problems

$doc = new DOMDocument();
    $doc->load('armstrong.xml');

    function outputIndi($indi) {
        $i = new DOMDocument();
        $i = $indi;

        echo '<li>';

        echo '<span class="edit fn">' . $indi->getElementsByTagName("fn") . '</span>'; // name not a real attribute, must access through DOM
        echo '<span class="edit bday">' . $indi->getElementsByTagName("bday") . '</span>'; // ditto
        // ...

        echo '<ul>';
        foreach ($indi->getElementsByTagName("family") as $subIndi) { // again, family not a real attribute
            outputIndi($subIndi);
        }
        echo '</ul>';

        echo '</li>';
    }

    outputIndi($doc->documentRoot);

    ?>

1 Answer 1

1

Here's your code. You'll need to add the rest of the attributes (dday, spouse)

RECURSION!

function outputIndi($indi) {
    echo '<li>';
    $id = $indi->getElementsByTagName('id')->item(0)->nodeValue;
    echo '<span class="vcard person" id="' . $id . '">';

    $fn = $indi->getElementsByTagName('fn')->item(0)->nodeValue;
    $bday = $indi->getElementsByTagName('bday')->item(0)->nodeValue;

    echo '<span class="edit fn">' . $fn . '</span>';
    echo '<span class="edit bday">' . $bday . '</span>';
    // ...

    echo '<ul>';
    $family = $indi->getElementsByTagName('family')->item(0)->childNodes;
    foreach ($family as $subIndi) {
        outputIndi($subIndi);
    }
    echo '</ul>';
    echo '</span>';
    echo '</li>';
}

$doc = new DOMDocument();
$doc->load('armstrong.xml');

outputIndi($doc->documentElement);

You see, it outputs all information about an "indi", loops through each child of <family>, and calls itself on that. Does that make sense?

Sign up to request clarification or add additional context in comments.

11 Comments

Yeah I think so, thanks! So is the initial value that I pass to outputIndi() the $doc variable I currently have? And when you say name, bday etc aren't real attributes, does that mean your code needs me to do something like getElementsByTagName?
Not quite... $doc->documentRoot. And yes, that's exactly right, getElementsByTagName.
Thanks I tried and I'm getting this error Fatal error: Call to a member function getElementsByTagName() on a non-object in /nfs/c05/h03/mnt/74985/domains/chris-armstrong.com/html/gortin/index.php on line 115
Do you know how I would get it to recognise $indi as an object?
Okay, I updated my answer. You almost had it, but not quite. It should work now, but my DOM skills are a bit rusty :|
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.