0

I am very new to coding and I have some practise exercises by my college and the first is to take an XML document and return the data using php which I have managed to do however the next step is to sort that data by either a new child element called 'note_id' or by adding an 'id' attribute to the note element and then show the data in descending order. I went with adding a new child element of note_id and I have inserted note_id number 6 in the middle of the other elements to see if it would sort.

I have tried numerous things by looking up information on the internet however I feel like I am just going round in circles as I am new to this and nothing seems to work (obviously as I don't know what I am doing - but got to start somewhere).

I haven't posted this question just to get an answer, I also need to understand how and why this method works if someone does reply with an answer.

My XML data is shown below and is stored in a file called 'note.xml'.

    <?xml version="1.0" encoding="UTF-8"?>
<notes>
<note>
<note_id>1</note_id>
<to>tove1</to>
<from>Jani1</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

<note>
<note_id>2</note_id>
<to>tove2</to>
<from>Jani2</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

<note>
<note_id>3</note_id>
<to>tove3</to>
<from>Jani3</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

<note>
<note_id>6</note_id>
<to>tove6</to>
<from>Jani6</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

<note>
<note_id>4</note_id>
<to>tove4</to>
<from>Jani4</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

<note>
<note_id>5</note_id>
<to>tove5</to>
<from>Jani5</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>

</notes>

My current PHP code is below which brings back the XML.

?php
// Loads the xml file.
$xml= simplexml_load_file("note.xml");
// Returns the top level xml element - notes.
echo $xml->getName() . "<br />";


// Returns each note element.
foreach($xml->note as $note){
     echo $note->getName() . ": " . $note . "<br />";
// Returns each child element of note element.
    foreach($note->children() as $child){
        echo $child->getName() . ": " . $child . "<br />";

    }

    echo "<br />";
}


echo "<br />";


?>
1

1 Answer 1

1

This is an example of how you could do it:

  • Load the note.xml file. In this case I have used a custom Note class which will load the file by passing it to the constructor.
  • You want to sort the xml by 'note_id'. To do this, you could convert the xml to an array of arrays where the arrays are essentially the notes.
  • Now that you have an array of arrays, you can sort these using the php native usort function:

  • Then, you can generate new xml based on the sorted array of arrays.

Example:

<?php
class Note
{
    /**
     * @var array
     */
    private $notes = [];

    /**
     * @param $fileName
     */
    public function __construct($fileName)
    {
        $xml = simplexml_load_file($fileName);
        $this->simpleXMLElementToArray($xml);
    }

    /**
     * Convert the SimpleXMLElement to array format.
     *
     * @param SimpleXMLElement $xml
     */
    protected function simpleXMLElementToArray(SimpleXMLElement $xml)
    {
        // For each note, create an associative array and add it to the $notes array
        foreach ($xml->note as $note) {
            $this->notes[] = json_decode(json_encode($note), true);
        }
    }

    /**
     * Sort the internal $notes array using usort.
     *
     * http://php.net/manual/en/function.usort.php
     */
    public function sortByNoteIdDescending()
    {
        usort($this->notes, array('Note', 'sortNotesArrayByNoteIdDescending'));
    }

    /**
     * Custom function to sort by note_id.
     *
     * @param array $note1
     * @param array $note2
     * @return int
     */
    protected function sortNotesArrayByNoteIdDescending(array $note1, array $note2)
    {
        if ($note1['note_id'] == $note2['note_id']) {
            return 0;
        } else if ($note1['note_id'] < $note2['note_id']) {
            return 1;
        } else {
            return -1;
        }
    }

    /**
     * Generate xml from the internal $notes array.
     */
    public function toXml()
    {
        $xml = new SimpleXMLElement('<notes/>');

        foreach ($this->notes as $note ) {
            $noteElement = $xml->addChild('note');
            $noteElement->addChild("note_id", $note["note_id"]);
            $noteElement->addChild("to", $note["to"]);
            $noteElement->addChild("from", $note["from"]);
            $noteElement->addChild("body", $note["body"]);
        }

        // To generate a nice output format
        $dom = dom_import_simplexml($xml)->ownerDocument;
        $dom->formatOutput = true;

        return $dom->saveXML();
    }
}

$note = new Note('note.xml');
$note->sortByNoteIdDescending();
echo $note->toXml();
Sign up to request clarification or add additional context in comments.

Comments

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.