简体   繁体   English

使用php Xpath更新xml文件

[英]update xml file with php Xpath

How to use use Xpath (php) update file? 如何使用使用Xpath(php)更新文件? My file structure: 我的文件结构:

<?xml version="1.0" encoding="ISO-8859-1"?>
<PersonList>
  <Person>
    <Name>Sonu Kapoor</Name>
    <Age>24</Age>
    <Gender>M</Gender>
    <PostalCode>54879</PostalCode>
  </Person>
  <Person>
    <Name>Jasmin</Name>
    <Age>28</Age>
    <Gender>F</Gender>
    <PostalCode>78745</PostalCode>
  </Person>
   <Person>
    <Name>Josef</Name>
    <Age>232</Age>
    <Gender>F</Gender>
    <PostalCode>53454</PostalCode>
  </Person>
</PersonList>

And i need change values Age and Gender where name is "Jasmin". 我需要更改值Age和Gender,其中name是“Jasmin”。 I try use google, but nothing good no found :( 我尝试使用谷歌,但没有找到好的:(

You can try simplexml 你可以试试simplexml

$xml = simplexml_load_string($str);
$obj = $xml->xpath('//Person[Name="Jasmin"]');
$obj[0]->Age = 30;
$obj[0]->Gender = 'M';
echo $xml->asXml();

/* or */ 
$xml->asXml($filename); <-- save xml into file

How to use use Xpath (php) update file? 如何使用使用Xpath(php)更新文件?

XPath is a query language for XML documents. XPath是XML文档的查询语言。 As such, an XPath expression cannot modify an XML document -- it can only select nodes or other data from it . 因此,XPath表达式无法修改XML文档 - 它只能从中选择节点或其他数据

A modified XML document can be produced with the help of the programming language that is hosting the XPath engine -- this may be XSLT, C#, Java, PHP, ... 一种改进的XML文档可以与正在托管XPath引擎编程语言的帮助下产生的-这可能是XSLT,C#,Java,PHP和...

And i need change values Age and Gender where name is "Jasmin". 我需要更改值Age和Gender,其中name是“Jasmin”。

Here is a simple XSLT transformation that produces a new XML document according to these requirements : 这是一个简单的XSLT转换,它根据这些要求生成一个新的XML文档

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my" exclude-result-prefixes="my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <my:params>
  <name>Jasmin</name>
  <age>31</age>
  <gender>X</gender>
 </my:params>

 <xsl:variable name="vParams" select=
 "document('')/*/my:params"/>

 <xsl:template match="node()|@*" name="identity">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match=
  "Person[Name=document('')/*/my:params/name]/Age">
  <Age><xsl:value-of select="$vParams/age"/></Age>
 </xsl:template>

 <xsl:template match=
  "Person[Name=document('')/*/my:params/name]/Gender">
  <Gender><xsl:value-of select="$vParams/gender"/></Gender>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the provided XML document : 当此转换应用于提供的XML文档时

<PersonList>
    <Person>
        <Name>Sonu Kapoor</Name>
        <Age>24</Age>
        <Gender>M</Gender>
        <PostalCode>54879</PostalCode>
    </Person>
    <Person>
        <Name>Jasmin</Name>
        <Age>28</Age>
        <Gender>F</Gender>
        <PostalCode>78745</PostalCode>
    </Person>
    <Person>
        <Name>Josef</Name>
        <Age>232</Age>
        <Gender>F</Gender>
        <PostalCode>53454</PostalCode>
    </Person>
</PersonList>

the wanted, correct result is produced : 产生了想要的正确结果

<PersonList>
   <Person>
      <Name>Sonu Kapoor</Name>
      <Age>24</Age>
      <Gender>M</Gender>
      <PostalCode>54879</PostalCode>
   </Person>
   <Person>
      <Name>Jasmin</Name>
      <Age>31</Age>
      <Gender>X</Gender>
      <PostalCode>78745</PostalCode>
   </Person>
   <Person>
      <Name>Josef</Name>
      <Age>232</Age>
      <Gender>F</Gender>
      <PostalCode>53454</PostalCode>
   </Person>
</PersonList>

You can use the DOMDocument from PHP. 您可以使用PHP中的DOMDocument。

You load your file and than loop trough the childNodes of the document. 您加载文件,而不是循环文档的childNodes。

<?php
$dom=new DOMDocument();
$dom->load("file.xml");

$root=$dom->documentElement; // This can differ (I am not sure, it can be only documentElement or documentElement->firstChild or only firstChild)

$nodesToDelete=array();

$markers=$root->getElementsByTagName('marker');

// Loop trough childNodes
foreach ($markers as $marker) {
    $type=$marker->getElementsByTagName('type')->item(0)->textContent;
    $title=$marker->getElementsByTagName('title')->item(0)->textContent;
    $address=$marker->getElementsByTagName('address')->item(0)->textContent;
    $latitude=$marker->getElementsByTagName('latitude')->item(0)->textContent;
    $longitude=$marker->getElementsByTagName('longitude')->item(0)->textContent;

    // Your filters here

    // To remove the marker you just add it to a list of nodes to delete
    $nodesToDelete[]=$marker;
}

// You delete the nodes
foreach ($nodesToDelete as $node) $node->parentNode->removeChild($node);

echo $dom->saveXML();
?>

You can save your output XML like this 您可以像这样保存输出XML

$dom->saveXML(); // This will return the XML as a string
$dom->save('file.xml'); // This saves the XML to a file

To do this parsing in JavaScript you should use jQuery (a small, but powerful library). 要在JavaScript中进行解析,您应该使用jQuery(一个小而强大的库)。

You can include the library directly from Google Code Repository. 您可以直接从Google Code Repository中包含该库。

<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"></script>

The library is cross-browser and very small. 该库是跨浏览器的,非常小。 It should be cached in many cases, because some sites use it from Google Code 它应该在很多情况下缓存,因为有些网站会使用Google代码

$(yourXMLStringOrDocument).find("marker").each(function () {
     var marker=$(this);

     var type=marker.find('type').text();
     var title=marker.find('title').text();
     var address=marker.find('address').text();
     var latitude=marker.find('latitude').text();
     var longitude=marker.find('longitude').text();
});

I know, I'm late. 我知道,我迟到了。 Here is a solution based on pure DOMXPath: 这是一个基于纯DOMXPath的解决方案:

<?php
$content = <<<XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<PersonList>
  <Person>
    <Name>Sonu Kapoor</Name>
    <Age>24</Age>
    <Gender>M</Gender>
    <PostalCode>54879</PostalCode>
  </Person>
  <Person>
    <Name>Jasmin</Name>
    <Age>28</Age>
    <Gender>M</Gender>
    <PostalCode>78745</PostalCode>
  </Person>
   <Person>
    <Name>Josef</Name>
    <Age>232</Age>
    <Gender>F</Gender>
    <PostalCode>53454</PostalCode>
  </Person>
</PersonList>
XML;

$doc = new DOMDocument();
$doc->loadXML($content);
$xp = new DOMXPath($doc);
$nodeList = $xp->query('/PersonList/Person[./Name="Jasmin"]/*');
for($i = 0; $i < $nodeList->length; $i++) {
    switch ($nodeList->item($i)->nodeName) {
        case 'Age':
            $nodeList->item($i)->nodeValue = 33;
            break;
        case 'Gender':
            $nodeList->item($i)->nodeValue = 'F';
            break;
    }
}
$doc->formatOutput = true;
echo $doc->saveXML();

http://3v4l.org/kqjoj http://3v4l.org/kqjoj

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM