Php 获取xml中的特定节点?
我的xml的结构如下:Php 获取xml中的特定节点?,php,simplexml,Php,Simplexml,我的xml的结构如下: <?xml version="1.0" ?> <users> <user> <name> foo </name> <token> jfhsjfhksdjfhsjkfhksjfsdk </token> <connection>
<?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
嗯,我不太明白,你能举个例子吗?谢谢