XML 文件 - 获取无限节点深度中的特定子节点 [英] XML File - Get specific child nodes in unlimited node depths

查看:67
本文介绍了XML 文件 - 获取无限节点深度中的特定子节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个使用分层数据的网站.在尝试使用 MySQL 数据库(真的很复杂...)之后,我决定深入研究 XML,因为听起来 XML 非常适合我的需求.

I'm working on a website that uses hierarchical data. After struggling to do it with MySQL databases (really complicated...), I decided to dive into XML because it sounds like XML works perfectly for my needs.

现在我正在试验 XML 文件和 SimpleXML.但首先,这是我的 XML 文件的样子:

Now I'm experimenting with an XML File and SimpleXML. But first of all, here is what my XML File looks like:

<?xml version="1.0" encoding="ISO-8859-1" ?>

<content>
    <parent>
        <child id="1">
            <title>child 1</title>

            <child id="1">
                <title>child 1.1</title>

                <child id="1">
                    <title>child 1.1.1</title>
                </child>
            </child>

            <child id="2">
                <title>child 1.2</title>

                <child id="1">
                    <title>child 1.2.1</title>

                        <child id="1">
                            <title>child 1.2.1.1</title>
                        </child>
                </child>

                <child id="2">
                    <title>child 1.2.2</title>
                </child>
            </child>

            <child id="3">
                <title>child 1.3</title>
            </child>
        </child>
    </parent>
</content>

如您所见,它具有不同深度"的子节点.我也不知道孩子的深度,因为他们是由网络应用程序创建的.这个深度或层数"可以变得相当高.

As you can see, it has a variing "depth" of child nodes. I also don't know the depth of childs, as they are created by the web app. This depth or "number of layers" can get quite high.

现在我想在我的网站上阅读这个 XML 文件.例如,我想将其可视化为一棵树,所有子节点都表示为连接到其父圆的圆.

Now I want to read this XML File in my website. For example, I want to visualize it as a tree, with all the child nodes represented as circles connected to their parent circle.

我已经设法让一个 foreach 获取所有第一层子"元素,然后另一个 foreach 获取所有第二层子"元素.问题是,这限制了我可以可视化的层数,因为我不能有十几个嵌套的 foreach'es.

I've managed to have a foreach getting all the first-layer "child" elements an then another foreach in it getting all second-layer "child" elements. The problem is, that this limits the number of layers I can visualize because I cannot have a dozen nested foreach'es.

现在我已经头疼地想到了一种无限嵌套的foreach结构"来获取子"节点的所有层的方法.但我找不到办法做到这一点.

Now I already have a headache thinking of a way of "unlimited nested foreach structures" to get all the layers of "child" nodes. But I'm not able to find a way of doing it.

你知道怎么做吗?请帮我!提前致谢.

Do you have an idea how to do it? Please help me! Thanks in advance.

PS:对不起我的英语,我是一名德国青少年学生 :)

PS: Sorry for my english, I'm an german teenager student :)

这是我的 test.php 中的代码:

Here is the code in my test.php:

<?php
    if (file_exists('mydata.xml'))
    {
        $xml = simplexml_load_file('mydata.xml');
?>

<ul>
<?php 
        foreach($xml->parent->child as $item) // Go through first layer
        {
            echo "<li>".$item->title;

            echo "<ul>"; // Open second layer <ul>
            foreach($item->child as $item) // Go through second layer
            {
                echo "<li>".$item->title."</li>";
            }
            echo "</ul>"; // Close second layer <ul>

            echo "</li>"; // Close child <li>
        }
    }
    else
    {
       exit('Konnte Datei nicht laden.');
    }
?>
</ul>

这就是结果,正是我所期望的:

This is the result, just what I was expecting:

- child 1

    - child 1.1
    - child 1.2
    - child 1.3

所以这很好用,但正如评论中提到的,我不仅需要第 1 层到第 2 层,还需要第 1 层到第 n 层.如果有人有想法,我将不胜感激:)

So this works fine, but as mentioned in the comments, I need this not only for layer 1 to 2, but for layer 1 to n. Would really appreciate if someone has an idea :)

推荐答案

下面是两个基本相同的示例.在每个函数中,我们定义了一个函数 renderNode(),它被递归调用以渲染嵌套列表.代码不多,就不多说了.

Two essentially identical examples are below. In each we define a function renderNode() that gets called recursively to render the nested lists. There's not a lot of code so there's not a lot to say.

一个基于 SimpleXML,因为这是您目前正在试验的内容.

One is based on SimpleXML, because that's what you're currently experimenting with.

另一个是基于DOM扩展,因为我个人觉得它是一个更好的 API(出于这里列出的所有原因,然后是一些.)

The other is based on the DOM extension, because I personally find it to be a better API to work with (for all the reasons listed here and then some.)

对于您在这里所做的事情,您使用的内容并不十分相关,但选项总是不错的.

For what you're doing here it's not terribly relevant which you use, but options are always nice.

$dom = new DOMDocument();
$dom->load('mydata.xml');
$xpath = new DOMXPath($dom);

echo "<ul>";
foreach ($xpath->query('/content/parent/child') as $node) {
    renderNode($node, $xpath);
}
echo "</ul>";

function renderNode(DOMElement $node, DOMXPath $xpath) {
    echo "<li>", $xpath->evaluate('string(title)', $node);
    $children = $xpath->query('child', $node);
    if ($children->length) {
        echo "<ul>";
        foreach ($children as $child) {
            renderNode($child, $xpath);
        }
        echo "</ul>";
    }
    echo "</li>";
};

<小时>

简单 XML 示例:

$xml = simplexml_load_file('mydata.xml');

echo "<ul>";
foreach ($xml->parent->child as $node) {
    renderNode($node);
}
echo "</ul>";

function renderNode($node) {
    echo "<li>", $node->title;
    if ($node->child) {
        echo "<ul>";
        foreach ($node->child as $child) {
            renderNode($child);
        }
        echo "</ul>";
    }
    echo "</li>";
}

<小时>

输出(美化,两个例子相同):

<ul>
    <li>child 1
        <ul>
            <li>child 1.1
                <ul><li>child 1.1.1</li></ul>
            </li>
            <li>child 1.2
                <ul>
                    <li>child 1.2.1
                        <ul><li>child 1.2.1.1</li></ul>
                    </li>
                    <li>child 1.2.2</li>
                </ul>
            </li>
            <li>child 1.3</li>
        </ul>
    </li>
</ul>

<小时>

只是为了好玩,这里有一个使用 XSLT 的奖励选项.美化后的输出和上面一样.


And just for kicks, here's a bonus option using XSLT. The beautified output is the same as above.

PHP:

$xmldoc = new DOMDocument();
$xmldoc->load('mydata.xml');

$xsldoc = new DOMDocument();
$xsldoc->load('example.xsl');

$xsl = new XSLTProcessor();
$xsl->importStyleSheet($xsldoc);
echo $xsl->transformToXML($xmldoc);

example.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html" encoding="UTF-8" indent="no"/>

    <xsl:template match="/content/parent">
        <ul>
            <xsl:apply-templates select="child"/>
        </ul>
    </xsl:template>
    <xsl:template match="child">
        <li>
            <xsl:value-of select="title"/>
            <xsl:if test="child">
                <ul>
                    <xsl:apply-templates select="child"/>
                </ul>
            </xsl:if>
        </li>
    </xsl:template>
</xsl:stylesheet>

这篇关于XML 文件 - 获取无限节点深度中的特定子节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆