是否获取XML中的特定节点? [英] Get specific node in xml?

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

问题描述

我的XML结构如下:

<?xml version="1.0" ?>
<users>
    <user>
        <name>
            foo
        </name>
        <token>
            jfhsjfhksdjfhsjkfhksjfsdk
        </token>
        <connection>
            <host>
                localhost
            </host>
            <username>
                root
            </username>
            <dbName>
                Test
            </dbName>
            <dbPass>
                123456789
            </dbPass>
        </connection>
    </user>
    <user>
        ... same structure...
    </user>
</users>

我编写了遍历所有XML节点的代码:

function getConString($node)
{
   $item = file_get_contents($_SERVER['DOCUMENT_ROOT'] . "con");
   $nodes = new SimpleXMLElement($item);
   $result = $nodes[0];

   foreach($result as $item => $value)
   {
      if($item == "token")
      {
         return $value->__toString();
     }
   }
}

我试图实现的是,当$node等于:

jfhsjfhksdjfhsjkfhksjfsdk

连接节点以数组形式返回,如何实现?

更新:

对于不理解的人,我只是希望如果我插入令牌:jfhsjfhksdjfhsjkfhksjfsdk将返回用户与令牌jfhsjfhksdjfhsjkfhksjfsdk的连接。因此,在本例中,我希望获取connection节点的所有内容并创建连接字符串:

<connection>
            <host>
                localhost
            </host>
            <username>
                root
            </username>
            <dbName>
                Test
            </dbName>
            <dbPass>
                123456789
            </dbPass>
        </connection>

xml

首先,有关推荐答案代码的一些注意事项。我不知道您的实际XML格式是否与上面完全相同,但如果是这样,必须强调的是,XML空格行为不同于HTML:通常没有DTD或XML模式定义,所有空格都是重要的空格,应该保留。此外,对于DTD或XML架构定义,内容中的空格非常重要

这意味着使用此XML:

<token>
    jfhsjfhksdjfhsjkfhksjfsdk
</token>
<token>取值' jfhsjfhksdjfhsjkfhksjfsdk '( =换行符),而不是'jfhsjfhksdjfhsjkfhksjfsdk'

这使得在不预先修改XML的情况下使用XPath查找令牌变得困难(您可以对其使用regex)。为此,您可以使用contains()XPath语法,但(理论上)它可以返回多个结果。

我不知道您是否测试了上面的代码,但也知道$value->__toString()返回类似' jfhsjfhksdjfhsjkfhksjfsdk '的内容(它可以根据缩进级别的不同而变化)。若要仅返回令牌值,您必须在:

中更改代码
return trim( $value->__toString() );

我的建议是无论如何都要这样更改您的XML:

<user>
    <name>foo</name>
    <token>jfhsjfhksdjfhsjkfhksjfsdk</token>
    <connection>
        <host>localhost</host>
        <username>root</username>
        <dbName>Test</dbName>
        <dbPass>123456789</dbPass>
    </connection>
</user>

因为这是最正确的数据存储方式:如果XML是您自己生成的,更改它应该不会太困难。

不管怎样,我建议您使用两个不同的函数--一个使用XPath,另一个不使用。

函数1(XPath)仅适用于修改后的XML:

function getConString( $token )
{
    $data = file_get_contents($_SERVER['DOCUMENT_ROOT'] . "con");
    $xml = new SimpleXMLElement( $data );

    $path = '//users/user/token[text()="'.$token.'"]';
    $found = $xml->xpath( $path );
    if( ! count( $found ) ) return False;

    $node = $found[0]->xpath('parent::*')[0];
    return (array) $node->connection;
}

函数2,处理旧的和新的XML:

function getConString( $token )
{
    $data = file_get_contents($_SERVER['DOCUMENT_ROOT'] . "con");
    $xml = new SimpleXMLElement( $data );

    foreach( $xml->user as $user )
    {
        if( trim($user->token->__toString()) == $token )
        {
            $retval = array();
            foreach( $user->connection[0] as $key => $val )
            { $retval[$key] = trim($val); }
            return $retval;
        }
    }

    return False;
}

编辑:

在注释中,您会问:"是否可以使用主机、数据库名等连接节点...将其分隔并保存在特定变量中"?

我不明白他们会造成什么问题:

$user = getConString( 'jfhsjfhksdjfhsjkfhksjfsdk' );
mysqli_connect ( $user['host'], $user['username'], $user['dbPass'], $user['dbName'] );

顺便说一下,您可以将返回值放在单独的变量中,方法如下:

$user = getConString( 'jfhsjfhksdjfhsjkfhksjfsdk' );
foreach( $user as $key => $val ) $$key = $val;
mysqli_connect ( $host, $username, $dbPass, $dbName );

或者--如果您需要特定的变量名称--按如下方式更改上面的第二个函数:

(...)
$retval = array();
foreach( $user->connection[0] as $key => $val )
{ $retval[] = trim($val); }
(...)

然后这样调用:

list( $dbHost, $dbUser, $dbDb, $dbPass ) = getConString( 'jfhsjfhksdjfhsjkfhksjfsdk' );
mysqli_connect ( $dbHost, $dbUser, $dbPass, $dbDb );

您可以将list中的变量名称更改为您喜欢的名称。函数修改是必要的,因为list 不适用于关联数组。


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

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