下面的例子是利用simplexml
这是一个亲密的朋友DOMDocument
。无论你使用哪种方法,显示的 xpath 都是相同的,我使用simplexml
这里是为了保持低代码。我将展示更高级的DOMDocument
稍后举例。
那么关于xpath:如何找到节点并更新它。首先如何找到节点:
该节点具有元素/标记名item
。你正在里面寻找它storagehouse
element,它是 XML 文档的根元素。全部item
文档中的元素在 xpath 中表达如下:
/storagehouse/item
首先从根源入手storagehouse
, then item
。除以/
。你已经知道了,所以有趣的部分是如何只采取那些item
具有特定 ID 的元素。为此,使用谓词并在末尾添加:
/storagehouse/item[@id="id"]
这将返回所有item
再次元素,但这次只有那些具有该属性的元素id
与价值id
(细绳)。例如,在您的情况下,使用以下 XML:
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<storagehouse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="schema.xsd">
<item id="c7278e33ef0f4aff88da10dfeeaaae7a">
<name>HDMI Cable 3m</name>
<weight>0.5</weight>
<category>Cables</category>
<location>B3</location>
</item>
<item id="df799fb47bc1e13f3e1c8b04ebd16a96">
<name>Dell U2410</name>
<weight>2.5</weight>
<category>Monitors</category>
<location>C2</location>
</item>
</storagehouse>
XML;
那个xpath:
/storagehouse/item[@id="df799fb47bc1e13f3e1c8b04ebd16a96"]
将返回计算机监视器(因为存在具有该 id 的此类项目)。如果有多个项目具有相同的 id 值,则将返回多个。如果没有,则不会返回。因此,让我们将其包装到代码示例中:
$simplexml = simplexml_load_string($xml);
$result = $simplexml->xpath(sprintf('/storagehouse/item[@id="%s"]', $id));
if (!$result || count($result) !== 1) {
throw new Exception(sprintf('Item with id "%s" does not exists or is not unique.', $id));
}
list($item) = $result;
在这个例子中,$titem
is the SimpleXMLElement http://php.net/SimpleXMLElement该计算机监视器的对象 xml 元素名称项目。
现在进行更改,这非常容易SimpleXML
在你的情况下:
$item->category = 'LCD Monitor';
最后看看结果:
echo $simplexml->asXML();
是的,这就是全部SimpleXML
在你的情况下。
如果你想这样做DOMDocument
,它的工作原理非常相似。但是,为了更新元素的值,您还需要访问该项目的子元素。让我们看看下面的示例,它首先也获取该项目。如果你与SimpleXML
上面的例子,你可以看到事情并没有真正的不同:
$doc = new DOMDocument();
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
$result = $xpath->query(sprintf('/storagehouse/item[@id="%s"]', $id));
if (!$result || $result->length !== 1) {
throw new Exception(sprintf('Item with id "%s" does not exists or is not unique.', $id));
}
$item = $result->item(0);
Again, $item
包含计算机监视器的项目 XML 元素。但这一次作为DOMElement http://php.net/DOMElement。要修改category
那里的元素(或者更准确地说,它是nodeValue
),需要首先获得孩子。您可以使用 xpath 再次执行此操作,但这次使用相对于$item
元素:
./category
假设总有一个category
中的子元素item
元素,可以写成这样:
$category = $xpath->query('./category', $item)->item(0);
$category
现在包含第一个category
的子元素$item
。剩下的就是更新它的值:
$category->nodeValue = "LCD Monitor";
最后看看结果:
echo $doc->saveXML();
就是这样。无论您选择 SimpleXML 还是 DOMDocument,这取决于您的需求。您甚至可以在两者之间切换。您可能想要映射并检查更改:
$repository = new Repository($xml);
$item = $repository->getItemByID($id);
$item->category = 'LCD Monitor';
$repository->saveChanges();
echo $repository->getXML();
自然这需要莫尔斯电码 https://gist.github.com/0f0a65234fa139b95ee1,对于这个答案来说太多了。