Php 获取xml中的特定节点?

Php 获取xml中的特定节点?,php,simplexml,Php,Simplexml,我的xml的结构如下: <?xml version="1.0" ?> <users> <user> <name> foo </name> <token> jfhsjfhksdjfhsjkfhksjfsdk </token> <connection>

我的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>
我试图实现的是,当$node等于:

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

更新:

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

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

本地服务器
根
试验
123456789

假设您不反对使用
DOMDocument
而不是
simpleXML
,那么您应该能够使用以下内容。如果没有,并且您必须使用
simpleXML
,则可以将XPath查询移植到
simpleXML->XPath

$strxml='<?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>';


/* an array to store details of connection */
$conndetails=array();
/* The particular value to be searched for in token nodes */
$var='jfhsjfhksdjfhsjkfhksjfsdk';


/* create the DOM objects & load xml source */
$dom=new DOMDocument;
$dom->loadXML( $strxml );
$xp=new DOMXPath( $dom );

/* Run the query to find the token with particular value - then it's next sibling */
$results=$xp->query('//token[contains( text(), "'.$var.'" )]/following-sibling::connection');

if( $results ){/* iterate through childnodes and store details in array */
    foreach( $results as $node ) {
        foreach( $node->childNodes as $child ) if( $child->nodeType==XML_ELEMENT_NODE ) $conndetails[ $child->tagName ]=$child->nodeValue;
    }
}

print_r( $conndetails );
$strxml='1!'
福
JFHSJFKSDJFHSJKFHKSJFSDK
本地服务器
根
试验
123456789
... 同样的结构。。。
';
/*存储连接详细信息的数组*/
$conndetails=array();
/*要在令牌节点中搜索的特定值*/
$var='JFHSJFKSDJFHSJKFHKSJFSDK';
/*创建DOM对象并加载xml源*/
$dom=新的DOMDocument;
$dom->loadXML($strxml);
$xp=新的DOMXPath($dom);
/*运行查询以查找具有特定值的令牌-然后它是下一个同级令牌*/
$results=$xp->query('//token[contains(text(),“'.$var.”))//following sibling::connection');
if($results){/*遍历子节点并将详细信息存储在数组中*/
foreach($results as$node){
foreach($node->childNodes as$child)如果($child->nodeType==XML\u ELEMENT\u node)$conndDetails[$child->tagName]=$child->nodeValue;
}
}
打印(详细信息);

您可以将这些选项中的一个设置为函数,但您应该能够了解如何执行此操作,查看此代码。这将向您展示如何检索所需的信息

备选案文1:

# using iteration
$data = new SimpleXMLElement($xml);
foreach ($data->item as $item){
    if ($item->user->token == 'jfhsjfhksdjfhsjkfhksjfsdk')
    {
        echo "host: " . $item->user->connection->host . "<br />";
        echo "username: " . $item->user->connection->username . "<br />";
        echo "dbName: " . $item->user->connection->dbName . "<br />";
        echo "dbPass: " . $item->user->connection->dbPass . "<br />";
    } else { continue; }
}
使用迭代 $data=新的simplexmlement($xml); foreach($data->item as$item){ 如果($item->user->token=='JFHSJFHKSJFSDK') { 回显“主机:”.$item->用户->连接->主机。“
”; 回显“用户名:”.$item->user->connection->username。“
”; 回显“dbName:”.$item->user->connection->dbName。“
”; 回显“dbPass:”.$item->user->connection->dbPass。“
”; }否则{继续;} } 备选案文2:

# using xpath
$data = new SimpleXMLElement($xml);
// Here we find the element token = jfhsjfhksdjfhsjkfhksjfsdk and get it's parent
$nodes = $data->xpath('//users/user/token[.="jfhsjfhksdjfhsjkfhksjfsdk"]/parent::*');
$user = $nodes[0];
echo "host: " . $user->connection->host . "<br />";
echo "username: " . $user->connection->username . "<br />";
echo "dbName: " . $user->connection->dbName . "<br />";
echo "dbPass: " . $user->connection->dbPass . "<br />";
使用xpath $data=新的simplexmlement($xml); //这里我们找到元素token=jfhsjfhksdjfhsjkfhksjfsdk并得到它的父元素 $nodes=$data->xpath('//users/user/token[.=“JFHSJFKSDJFHSJKFHKSJFSDK”]/parent::*); $user=$nodes[0]; 回声“主机:”$用户->连接->主机。“
”; echo“用户名:”$用户->连接->用户名。“
”; echo“dbName:”$用户->连接->数据库名。“
”; 回显“dbPass:”$用户->连接->数据库传递。“
”;
首先,关于XML代码的一些注意事项。我不知道您真正的XML的格式是否与上面所述完全相同,但如果确实如此,则必须强调XML空白行为不同于HTML:通常在没有DTD或XML模式定义的情况下,所有空白都是重要的空白,应该保留。同样对于DTD或XML模式定义,内容中的空白也很重要

这意味着使用此XML:

<token>
    jfhsjfhksdjfhsjkfhksjfsdk
</token>
我的建议是以以下方式更改XML:

<user>
    <name>foo</name>
    <token>jfhsjfhksdjfhsjkfhksjfsdk</token>
    <connection>
        <host>localhost</host>
        <username>root</username>
        <dbName>Test</dbName>
        <dbPass>123456789</dbPass>
    </connection>
</user>
$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 );
函数2,用于新旧XML: 编辑: 在注释中,您会问:“是否可以将连接节点(如主机、数据库名等)分离并保存在特定变量中”

我不明白他们会产生什么问题,这种语法:

$user = getConString( 'jfhsjfhksdjfhsjkfhksjfsdk' );
mysqli_connect ( $user['host'], $user['username'], $user['dbPass'], $user['dbName'] );
顺便说一句,您可以通过以下方式将返回值放在单独的变量中:

<user>
    <name>foo</name>
    <token>jfhsjfhksdjfhsjkfhksjfsdk</token>
    <connection>
        <host>localhost</host>
        <username>root</username>
        <dbName>Test</dbName>
        <dbPass>123456789</dbPass>
    </connection>
</user>
$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 );
或者-如果您需要特定的变量名-用以下方式更改上面的第二个函数:

<user>
    <name>foo</name>
    <token>jfhsjfhksdjfhsjkfhksjfsdk</token>
    <connection>
        <host>localhost</host>
        <username>root</username>
        <dbName>Test</dbName>
        <dbPass>123456789</dbPass>
    </connection>
</user>
$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 );
然后这样称呼它:

<user>
    <name>foo</name>
    <token>jfhsjfhksdjfhsjkfhksjfsdk</token>
    <connection>
        <host>localhost</host>
        <username>root</username>
        <dbName>Test</dbName>
        <dbPass>123456789</dbPass>
    </connection>
</user>
$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 );
您可以使用首选名称更改
列表中的变量名称。由于
列表
不适用于关联数组


  • 了解更多关于
  • 了解更多关于

您想要一个函数,在这个函数中,您可以通过令牌搜索xml,然后将连接作为数组返回?这看起来效率很低。还可以为每个用户创建一个xml,文件名为token。然后打开该文件并提取信息。我得到
试图获取条件中非对象的属性。这是我函数中
$nodes
的值:非常好的解释@fusion3k,我只想问一个问题:是否可以使用连接节点,如主机、数据库名等。。。分离并保存在一个特定的变量中?我不明白。您需要4个变量,如$host、$username等。。?如果是,你什么时候想要?在全局范围内?正是为了创建一个连接字符串并返回要放入mysqliyou的连接字符串,您可以轻松地使用array:
mysqli_connect($array['host'],$array['username'],$array['dbPass'],$array['dbName'])
否则,您可以用这种方式修改第二个函数
$retval[]=trim($val)list($host,$user,$db,$pass)=getConString2('jfhsjfhksdjfhsjkfhkfsdk')调用它:然后使用变量
$host
$user
$db
$pass
嗯,我不太明白,你能举个例子吗?谢谢