从XML导出定义的元素

时间:2011-12-16 21:34:44

标签: php xml parsing

我想导出(或保留)XML中已定义属性的子标签。由于我不知道这个过程的名称,我在网上找不到任何相关信息。由于很难解释,我决定为我的问题举一个例子。

假设我有这个XML文件:

<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>

我必须解析结果并仅保留具有<url>属性的行。像这样:

xml parsing

解析后,我必须在新的XML文件中组合这些行,最终结果必须如下:

<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>

通常我想在PHP中执行此过程,但也可能在其他语言中。 所以,如果您有任何想法来解决这个问题,请发表评论。

2 个答案:

答案 0 :(得分:3)

我会使用xpath查询来查找行节点内的所有url节点。然后,只需将您找到的每个url元素的父节点附加到新的DomDocument,如下所示:

$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();

答案 1 :(得分:1)

我使用simplexml作为您的输入读取,因此您的解析将很容易。然后,我将创建一个递归函数,例如:

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

现在这还远未完成,但你可以让它递归调用每个孩子。如果返回true,则表示您发现了一个URL为子节点的节点。使用该$ element节点,例如将其添加到simplexmlelements数组中,然后将其预先复制回XML。

这有意义吗?