使用DOMXml和Xpath更新XML条目 [英] Using DOMXml and Xpath, to update XML entries

查看:41
本文介绍了使用DOMXml和Xpath更新XML条目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我知道关于这三个主题结合在一起以更新XML条目有很多问题,但是似乎每个人都非常特定于特定问题。



I一直花一些时间试图了解XPath及其方式,但是我仍然无法做我需要做的事情。



在这里,我们走



我有这个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电缆3m< / name>
< weight> 0.5< / weight>
< category>电缆< / category>
< location> B3< / location>
< / item>
< item id = df799fb47bc1e13f3e1c8b04ebd16a96>
< name> Dell U2410< / name>
< weight> 2.5< / weight>
< category>监视器< / category>
< location> C2< / location>
< / item>
< / storagehouse>

我想做的是在需要时更新/编辑上面的任何节点。我将为此做一个HTML表格。
但是我最大的困扰是如何找到并更新所需的节点并进行更新?



这里我有一些我想做的事情

 <?php 

函数fnDOMEditElementCond()
{
$ dom =新的DOMDocument();
$ dom-> load('storage.xml');
$ library = $ dom-> documentElement;
$ xpath =新的DOMXPath($ dom);
//我在这里有点理解
$ result = $ xpath-> query(’/ storagehouse / item [1] / name’);
//这个不是很多
$ result-> item(0)-> nodeValue。=‘Series’;
//将删除元素的CDATA属性。
//要保留该元素,请删除此元素(请参见删除示例)&用CDATA重新创建它(请参见例如创建xml)。

//第二种方式
// $ result = $ xpath-> query(’/ library / book [author = J.R.R.Tolkein]');
// // $ result-> item(0)-> getElementsByTagName(’title’)-> item(0)-> nodeValue。=’Series';
标头(内容类型:文本/ xml);
echo $ dom-> saveXML();


}
?>

有人可以给我一个带有属性的示例,依此类推,因此用户决定更新一个所需的节点,我可以使用XPath找到该节点,然后对其进行更新?

解决方案

下面的示例利用 simplexml DOMDocument 的朋友。无论使用哪种方法,显示的xpath都是相同的,我在这里使用 simplexml 来保持较低的代码。稍后,我将显示一个更高级的 DOMDocument 示例。



关于xpath:如何查找节点并更新它。首先,如何找到节点:



该节点具有元素/标记名 item 。您正在 storagehouse 元素中寻找它,这是XML文档的根元素。文档中所有 item 元素均在xpath中表示为:

  / storagehouse / item 

从根开始,第一个 storagehouse ,然后是项目。除以 / 。您已经知道了,所以有趣的部分是如何仅采用具有特定ID的 item 元素。为此,使用谓词并在末尾添加谓词:

  / storagehouse / item [@ id = id] 

这将再次返回所有 item 元素,但这仅对具有 id 属性且值为 id (字符串)的对象计时。例如,在使用以下XML的情况下:

  $ xml =<<< XML 
< ?xml版本= 1.0编码= UTF-8?>
< storagehouse xmlns:xsi = http://www.w3.org/2001/XMLSchema-instance
xsi:noNamespaceSchemaLocation = schema.xsd>
< item id = c7278e33ef0f4aff88da10dfeeaaae7a>
< name> HDMI电缆3m< / name>
< weight> 0.5< / weight>
< category>电缆< / category>
< location> B3< / location>
< / item>
< item id = df799fb47bc1e13f3e1c8b04ebd16a96>
< name> Dell U2410< / name>
< weight> 2.5< / weight>
< category>监视器< / 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){
抛出new Exception(sprintf('id为%s的项目不存在或不唯一。', $ id));
}
list($ item)= $ result;

在此示例中, $ titem 是该计算机监视器xml元素名称项的 SimpleXMLElement 对象。 / p>

因此,现在进行更改,对于您而言,使用 SimpleXML 极其容易:

  $ item->类别='LCD显示器'; 

最后看到结果:

  echo $ simplexml-> asXML(); 

是的,所有情况下都是 SimpleXML



如果要使用 DOMDocument 进行此操作,则其工作原理非常相似。但是,要更新元素的值,您还需要访问该项目的子元素。让我们看下面的示例,该示例首先还提取项目。如果与上面的 SimpleXML 示例进行比较,您会发现事情并没有真正的不同:

  $ doc = new DOMDocument(); 
$ doc-> loadXML($ xml);
$ xpath =新的DOMXPath($ doc);
$ result = $ xpath-> query(sprintf(’/ storagehouse / item [@id =%s]',$ id));
if(!$ result || $ result-> length!== 1){
throw new Exception(sprintf('id为%s的项目不存在或不唯一。 ,$ id));
}
$ item = $ result-> item(0);

再次, $ item 包含XML计算机监视器的元素。但这一次是 DOMElement 。要修改其中的 category 元素(或更准确地说,是 nodeValue ),需要先获得孩子。您可以使用xpath再次执行此操作,但是这次使用相对于 $ item 元素的表达式:

  ./类别

假定始终存在<$ c $在项目元素中的c>类别子元素,可以这样写:

  $ category = $ xpath-> query('./ category',$ item)-> item(0); 

$ category 现在确实包含第一个< $ item 的code> category 子元素。剩下的就是更新它的值:

  $ category-> nodeValue = LCD监视器; 

最后看到结果:

  echo $ doc-> saveXML(); 

就是这样。无论您选择SimpleXML还是DOMDocument,这取决于您的需求。您甚至可以在两者之间切换。您可能要映射并检查更改:

  $ repository = new Repository($ xml); 
$ item = $ repository-> getItemByID($ id);
$ item-> category = LCD显示器;
$ repository-> saveChanges();
echo $ repository-> getXML();

自然地,这需要更多代码,对于此答案而言,太多了。


Hello I know there is many questions here about those three topics combined together to update XML entries, but it seems everyone is very specific to a given problem.

I have been spending some time trying to understand XPath and its way, but I still can't get what I need to do.

Here we go

I have this XML file

 <?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>

What I would like to do is to update/edit any of the nodes above when I need to. I will do a Html form for that. But my biggest conserne is how do I find and update a the desired node and update it?

Here I have some of what I am trying to do

<?php

 function fnDOMEditElementCond()
   {
       $dom = new DOMDocument();
       $dom->load('storage.xml');
       $library = $dom->documentElement;
       $xpath = new DOMXPath($dom);
      // I kind of understand this one here
       $result = $xpath->query('/storagehouse/item[1]/name');
       //This one not so much
       $result->item(0)->nodeValue .= ' Series';
       // This will remove the CDATA property of the element.
       //To retain it, delete this element (see delete eg) & recreate it with CDATA (see create xml eg).

       //2nd Way
       //$result = $xpath->query('/library/book[author="J.R.R.Tolkein"]');
      // $result->item(0)->getElementsByTagName('title')->item(0)->nodeValue .= ' Series';
       header("Content-type: text/xml");
       echo $dom->saveXML();


   }
?>

Could someone maybe give me an examples with attributes and so on, so one a user decides to update a desired node, I could find that node with XPath and then update it?

解决方案

The following example is making use of simplexml which is a close friend of DOMDocument. The xpath shown is the same regardless which method you use, and I use simplexml here to keep the code low. I'll show a more advanced DOMDocument example later on.

So about the xpath: How to find the node and update it. First of all how to find the node:

The node has the element/tagname item. You are looking for it inside the storagehouse element, which is the root element of your XML document. All item elements in your document are expressed like this in xpath:

/storagehouse/item

From the root, first storagehouse, then item. Divided with /. You already know that, so the interesting part is how to only take those item elements that have the specific ID. For that the predicate is used and added at the end:

/storagehouse/item[@id="id"]

This will return all item elements again, but this time only those which have the attribute id with the value id (string). For example in your case with the following 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;

that xpath:

/storagehouse/item[@id="df799fb47bc1e13f3e1c8b04ebd16a96"]

will return the computer monitor (because such an item with that id exists). If there would be multiple items with the same id value, multiple would be returned. If there were none, none would be returned. So let's wrap that into a code-example:

$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;

In this example, $titem is the SimpleXMLElement object of that computer monitor xml element name item.

So now for the changes, which are extremely easy with SimpleXML in your case:

$item->category = 'LCD Monitor';

And to finally see the result:

echo $simplexml->asXML();

Yes that's all with SimpleXML in your case.

If you want to do this with DOMDocument, it works quite similar. However, for updating an element's value, you need to access the child element of that item as well. Let's see the following example which first of all fetches the item as well. If you compare with the SimpleXML example above, you can see that things not really differ:

$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 contains the item XML element of the computer monitor. But this time as a DOMElement. To modify the category element in there (or more precisely it's nodeValue), that children needs to be obtained first. You can do this again with xpath, but this time with an expression relative to the $item element:

./category

Assuming that there always is a category child-element in the item element, this could be written as such:

$category = $xpath->query('./category', $item)->item(0);

$category does now contain the first category child element of $item. What's left is updating the value of it:

$category->nodeValue = "LCD Monitor";

And to finally see the result:

echo $doc->saveXML();

And that's it. Whether you choose SimpleXML or DOMDocument, that depends on your needs. You can even switch between both. You probably might want to map and check for changes:

$repository = new Repository($xml);
$item = $repository->getItemByID($id);
$item->category = 'LCD Monitor';
$repository->saveChanges();
echo $repository->getXML();

Naturally this requires more code, which is too much for this answer.

这篇关于使用DOMXml和Xpath更新XML条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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