使用变量作为XML的对象引用

时间:2022-06-09 16:09:23

Let's say I have a XML file like this one:

假设我有一个这样的XML文件:

<?xml version="1.0" encoding="utf-8"?>

<test>
    <foo>
        <bar>Hello, World!</bar>
    </foo>
</test>

So, if I use something like this I can echo Hello, World!:

所以,如果我用这样的东西,我可以回应你好,世界!

<?php
$xml = simplexml_load_file("myxml.xml");
echo $xml->foo->bar;
?>

But, what if I want to refer to bar with a variable?

但是,如果我想用一个变量来表示bar呢?

<?php
$xml = simplexml_load_file("myxml.xml");
$reference = "foo->bar";
echo $xml->$reference;
?>

That won't work. Any solution?

是行不通的。有解决方案吗?

3 个解决方案

#1


1  

You can't do that because it will look for a property with the literal foo->bar, and not bar inside foo.

你不能这样做,因为它会寻找一个属性符为foo->,而不是foo内的bar。


You could do it like this:

你可以这样做:

$xml = simplexml_load_file("myxml.xml");

$reference = "foo->bar";
$tmp = $xml;
foreach(explode('->', $reference) as $v){
    $tmp = $tmp->$v;
}
echo $tmp;

Output:

输出:

Hello, World!

你好,世界!



This would work even if you don't want to go until the last element. Take a look at the following example.

即使您不希望在最后一个元素之前执行,它也可以工作。请看下面的示例。

Test with this XML:

这个XML测试:

<?xml version="1.0" encoding="utf-8"?>

<test>
    <foo>
        <bar>Hello, World!</bar>
        <something>
            <values>
                <v1>Some value here (1)</v1>
                <v2>Some value here (2)</v2>
                <v3>Some value here (3)</v3>
                <v4>Some value here (4)</v4>
            </values>
        </something>
    </foo>
</test>

Now, change to $reference = "foo->something->values"; and from echo $tmp; to print_r($tmp);. This will be the output:

现在,改为$reference = "foo->something->值";从回波tmp美元;print_r(tmp);。这是输出:

SimpleXMLElement Object
(
    [v1] => Some value here (1)
    [v2] => Some value here (2)
    [v3] => Some value here (3)
    [v4] => Some value here (4)
)

#2


2  

It's because you are trying to access 3rd level in one variable. PHP couldn't handle -> in variable.

这是因为您试图在一个变量中访问第3层。PHP无法处理变量中的->。

$level1 = 'foo';
$level2 = 'bar';

echo $xml->$level1->$level2;

#3


1  

Use Xpath. It allows you to use expressions to fetch parts of an XML.

使用Xpath。它允许您使用表达式来获取XML的部分。

$xml = <<<'XML'
<?xml version="1.0" encoding="utf-8"?>
<test>
    <foo>
        <bar>Hello, World!</bar>
    </foo>
</test>
XML;

$xml = new SimpleXMLElement($xml);
$expression = 'foo/bar';

var_dump(
  (string)$xml->xpath($expression)[0]
);

Xpath is a really powerful tool. However to use the full potential you will have to use DOMXpath::evaluate(). SimpleXMLElement::xpath() can only return node lists as arrays of SimpleXMLElement objects. DOMXpath:evaluate() can return node lists or scalar values.

Xpath是一个非常强大的工具。但是,要使用全部潜能,您必须使用DOMXpath::evaluate()。SimpleXMLElement::xpath()只能作为SimpleXMLElement对象的数组返回节点列表。DOMXpath:evaluate()可以返回节点列表或标量值。

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$expression = 'string(foo/bar)';

var_dump(
  $xpath->evaluate($expression)
);

#1


1  

You can't do that because it will look for a property with the literal foo->bar, and not bar inside foo.

你不能这样做,因为它会寻找一个属性符为foo->,而不是foo内的bar。


You could do it like this:

你可以这样做:

$xml = simplexml_load_file("myxml.xml");

$reference = "foo->bar";
$tmp = $xml;
foreach(explode('->', $reference) as $v){
    $tmp = $tmp->$v;
}
echo $tmp;

Output:

输出:

Hello, World!

你好,世界!



This would work even if you don't want to go until the last element. Take a look at the following example.

即使您不希望在最后一个元素之前执行,它也可以工作。请看下面的示例。

Test with this XML:

这个XML测试:

<?xml version="1.0" encoding="utf-8"?>

<test>
    <foo>
        <bar>Hello, World!</bar>
        <something>
            <values>
                <v1>Some value here (1)</v1>
                <v2>Some value here (2)</v2>
                <v3>Some value here (3)</v3>
                <v4>Some value here (4)</v4>
            </values>
        </something>
    </foo>
</test>

Now, change to $reference = "foo->something->values"; and from echo $tmp; to print_r($tmp);. This will be the output:

现在,改为$reference = "foo->something->值";从回波tmp美元;print_r(tmp);。这是输出:

SimpleXMLElement Object
(
    [v1] => Some value here (1)
    [v2] => Some value here (2)
    [v3] => Some value here (3)
    [v4] => Some value here (4)
)

#2


2  

It's because you are trying to access 3rd level in one variable. PHP couldn't handle -> in variable.

这是因为您试图在一个变量中访问第3层。PHP无法处理变量中的->。

$level1 = 'foo';
$level2 = 'bar';

echo $xml->$level1->$level2;

#3


1  

Use Xpath. It allows you to use expressions to fetch parts of an XML.

使用Xpath。它允许您使用表达式来获取XML的部分。

$xml = <<<'XML'
<?xml version="1.0" encoding="utf-8"?>
<test>
    <foo>
        <bar>Hello, World!</bar>
    </foo>
</test>
XML;

$xml = new SimpleXMLElement($xml);
$expression = 'foo/bar';

var_dump(
  (string)$xml->xpath($expression)[0]
);

Xpath is a really powerful tool. However to use the full potential you will have to use DOMXpath::evaluate(). SimpleXMLElement::xpath() can only return node lists as arrays of SimpleXMLElement objects. DOMXpath:evaluate() can return node lists or scalar values.

Xpath是一个非常强大的工具。但是,要使用全部潜能,您必须使用DOMXpath::evaluate()。SimpleXMLElement::xpath()只能作为SimpleXMLElement对象的数组返回节点列表。DOMXpath:evaluate()可以返回节点列表或标量值。

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$expression = 'string(foo/bar)';

var_dump(
  $xpath->evaluate($expression)
);