开发者

update xml file with php Xpath

开发者 https://www.devze.com 2023-01-31 13:23 出处:网络
How to use use Xpath (php) update file? My file structure: <?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>

How to use use Xpath (php) update file? 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". I try use google, but nothing good no found :(


You can try 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 is a query language for XML documents. As such, an XPath expression cannot modify an XML document -- it can only select nodes or other data from it.

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, ...

And i need change values Age and Gender where name is "Jasmin".

Here is a simple XSLT transformation that produces a new XML document according to these requirements:

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

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

You load your file and than loop trough the childNodes of the document.

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

$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).

You can include the library directly from 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

$(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:

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

0

精彩评论

暂无评论...
验证码 换一张
取 消