anon
anon

Reputation:

Exporting defined elements from XML

I would like to export (or to keep) the subtags which are with the defined attribute in XML. As I don't know the name of this process, I can't find any relevant information about it on the net. And since it's hard to explain, I decided to put an examples for my issue.

Let's say, I have this XML file:

<results>
    <result idSite="1">
        <row>
            <label>category</label>
            <visits>2</visits>
            <idsubdatatable>5</idsubdatatable>
            <subtable>
                <row>
                    <label>uncategorized</label>
                    <visits>2</visits>
                    <idsubdatatable>6</idsubdatatable>
                    <subtable>
                        <row>
                            <label>/index</label>
                            <visits>2</visits>
                            <url>http://mysite1.com/category/uncategorized/</url>
                        </row>
                    </subtable>
                </row>
            </subtable>
        </row>
        <row>
            <label>about</label>
            <visits>1</visits>
            <idsubdatatable>7</idsubdatatable>
            <subtable>
                <row>
                    <label>/index</label>
                    <visits>1</visits>
                    <url>http://mysite1.com/about/</url>
                </row>
            </subtable>
        </row>
    </result>
    <result idSite="2">
        <row>
            <label>/calendar</label>
            <visitors>1</visitors>
            <url>http://mysite2.com/calendar</url>
        </row>
    </result>
</results>

And I have to parse the results and keep only the rows which are with a <url> attribute. Like this:

xml parsing

After parsing I have to combine these rows in a new XML file, and the final result must be like this:

<result>
<row>
    <label>/index</label>
    <visits>2</visits>
    <url>http://mysite1.com/category/uncategorized/</url>
</row>
<row>
    <label>/index</label>
    <visits>1</visits>
    <url>http://mysite1.com/about/</url>
</row>
<row>
    <label>/calendar</label>
    <visitors>1</visitors>
    <url>http://mysite2.com/calendar</url>
</row>
</result>

Generally I want to do this process in PHP but it maybe in other languages too. So, if you have any idea to solve this problem, please comment.

Upvotes: 1

Views: 131

Answers (2)

user895378
user895378

Reputation:

I would use an xpath query to find all url nodes inside row nodes. Then, just append the parent node of each url element you find to a new DomDocument like so:

$xml = '...';
$dom = new DomDocument();
$dom->preserveWhiteSpace = FALSE;
$dom->loadXML($xml);

$new_dom = new DomDocument();
$result = $new_dom->createElement('result');
$new_dom->appendChild($result);

$xpath = new DOMXPath($dom);
$rows = $xpath->query('//row/url');

for ($i=0;$i<$rows->length;$i++) {
  $node = $new_dom->importNode($rows->item($i)->parentNode, TRUE);
  $result->appendChild($node);
}

$new_dom->formatOutput = TRUE;
echo $new_dom->saveXML();

Upvotes: 3

Mathieu Dumoulin
Mathieu Dumoulin

Reputation: 12244

I'd use simplexml to read as your input, so your parsing would be easy. And then, i'd create a recursive function such as:

function isUrlElement($element){
    foreach($element->children() as $children){
        if($children->getName() == 'url'){
            return true;
        }else{
            isUrlElement($children);
        }
    }
}

Now this is far from complete, but you could make it recursive calling it for each children. When this returns true, you'd know you found a node that has URL as a children. Use that $element node to for example add it to an array of simplexmlelements and then just foreach it back into XML.

Does that make sense?

Upvotes: 1

Related Questions