get values from Xpath - php

Below is my xml with namespace
<?xml version="1.0" encoding="UTF-8"?>
<hotels xmlns="http://www.test.com/schemas/messages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaLocation="http://www.test.com/schemas/messages">
<hotel >
<rooms>
<room>
<rates>
<rate id="1" adults="1" child="0"></rate>
<rate id="2" adults="2" child="0"></rate>
<rate id="3" adults="1" child="0"></rate>
</rates>
</room>
<room>
<rates>
<rate id="4" adults="1" child="0"></rate>
<rate id="5" adults="2" child="0"></rate>
<rate id="6" adults="2" child="0"></rate>
</rates>
</room>
</rooms>
</hotel>
</hotels>
i trying below php code (xpath) using foreach to get values of the ratenode
$xd = simplexml_load_file('C:/inetpub/vhosts/test.com/data_download/q.xml');
$xd->registerXPathNamespace("n", "http://www.test.com/schemas/messages");
foreach($xd->xpath("//n:hotels/n:hotel") as $xd_item)
{
echo 'item - A';
foreach($xd_item->xpath("rooms/room") as $xd_room)
{
foreach($xd_room->xpath("rates/rate") as $xd_rate)
{
echo 'rate - C';
}
}
}
In the foreach of $xd_item is not working. I mean the 2nd foreach its end with the value "echo 'item - A';" anyone can help me?

The problem with your codes is, as mentioned by #kjhughes in his comment, that some elements are in the default namespace but your XPath missed to use the corresponding prefix on those elements. Also, your code prints static literal strings i.e 'item - A' and 'rate - C', not any part of the XML being parsed.
" Is possible to write conditions like $xd->xpath("rates/rate[#id='1']") in dom"
Yes it is possible. It is also possible using SimpleXML, for example :
$xd->registerXPathNamespace("n", "http://www.test.com/schemas/messages");
foreach($xd->xpath("//n:rate[#id='1']") as $rate){
echo $rate["id"] .", ". $rate["adults"] .", ". $rate["child"] ."\r\n";
}
eval.in demo
output :
//id, adults, rate
1, 1, 0

The variable $xd_item is of type SimpleXMLElement from which you can access its room properties like this for example:
$xd_item->rooms->room
This will return an object of type SimpleXMLElement from which you can get the rates and you can loop using a foreach. The values that you want from the 'rate' are in the attributes
For example:
$xd = simplexml_load_file('C:/inetpub/vhosts/test.com/data_download/q.xml');
$xd->registerXPathNamespace("n", "http://www.test.com/schemas/messages");
foreach($xd->xpath("//n:hotels/n:hotel") as $xd_item)
{
foreach($xd_item->rooms->room as $room) {
foreach ($room->rates->rate as $rate) {
echo sprintf(
'id: %s<br>adults: %s<br>child: %s<br><br>',
$rate->attributes()->id->__toString(),
$rate->attributes()->adults->__toString(),
$rate->attributes()->child->__toString()
);
}
}
}

Related

Getting data from XML nodes

I am a beginner on PHP and XML.
I have a XML file as below (partly):
<combination>
<id_combination>2289</id_combination>
<quantity>4</quantity>
<unit_price_impact>0.000000</unit_price_impact>
<reference>K10100.1B</reference>
<group_name>Color</group_name>
<attribute_name>Blue</attribute_name>
</combination>
<combination>
<id_combination>2289</id_combination>
<quantity>4</quantity>
<unit_price_impact>0.000000</unit_price_impact>
<reference>K10100.1B</reference>
<group_name>Size</group_name>
<attribute_name>1</attribute_name>
</combination>
<combination>
<id_combination>2290</id_combination>
<quantity>20</quantity>
<unit_price_impact>0.000000</unit_price_impact>
<reference>K10100.2B</reference>
<group_name>Color</group_name>
<attribute_name>Blue</attribute_name>
</combination>
<combination>
<id_combination>2290</id_combination>
<quantity>20</quantity>
<unit_price_impact>0.000000</unit_price_impact>
<reference>K10100.2B</reference>
<group_name>Size</group_name>
<attribute_name>2</attribute_name>
</combination>
And i desire to get an array as described below:
$id_combination => 2289
$reference => K10100.1B
$combination_name => Color: Blue / Size: 1
$quantity => 4
$id_combination => 2290
$reference => K10100.2B
$combination_name => Color: Blue / Size: 2
$quantity => 20
I want to join data with the same 'id_combination' nodes and then process it in PHP.
I tried to use "foreach" loop, "array_unique", "implode" and etc.. but wasn't able to get any success.
I would appreciate anyone would help me straight to result with the suggested code.
i just did the following changes to your xml and have append new code and look and worked on my xampp server
$xml='<?xml version="1.0" encoding="UTF8"?>
<combinations>
<combination>
<id_combination>2289</id_combination>
<quantity>4</quantity>
<unit_price_impact>0.000000</unit_price_impact>
<reference>K10100.1B</reference>
<group_name>Color</group_name>
<attribute_name>Blue</attribute_name>
</combination>
<combination>
<id_combination>2289</id_combination>
<quantity>4</quantity>
<unit_price_impact>0.000000</unit_price_impact>
<reference>K10100.1B</reference>
<group_name>Size</group_name>
<attribute_name>1</attribute_name>
</combination>
<combination>
<id_combination>2290</id_combination>
<quantity>20</quantity>
<unit_price_impact>0.000000</unit_price_impact>
<reference>K10100.2B</reference>
<group_name>Color</group_name>
<attribute_name>Blue</attribute_name>
</combination>
<combination>
<id_combination>2290</id_combination>
<quantity>20</quantity>
<unit_price_impact>0.000000</unit_price_impact>
<reference>K10100.2B</reference>
<group_name>Size</group_name>
<attribute_name>2</attribute_name>
</combination>
</combinations>';
$xmlobject = simplexml_load_string($xml);
echo '<pre>';
// this print an array of objects
print_r($xmlobject);
// this print the associative array
print_r((array)$xmlobject);
Consider an XSLT solution as this is a typical need for the Muenchian Method in XSLT 1.0 used to group nodes by various keys. As information, XSLT is a special-purpose language designed to transform XML files and like most general purpose languages, PHP maintains an XSLT processor.
XSLT Script (save as .xsl to be loaded in script below)
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:key name="idkey" match="combination" use="id_combination" />
<xsl:template match="combinations">
<xsl:copy>
<xsl:apply-templates select="combination[generate-id() =
generate-id(key('idkey',id_combination)[1])]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="combination[generate-id() =
generate-id(key('idkey',id_combination)[1])]">
<xsl:copy>
<xsl:copy-of select="id_combination|quantity|unit_price_impact|reference"/>
<combination_name>
<xsl:for-each select="key('idkey',id_combination)">
<xsl:value-of select="concat(group_name, ': ', attribute_name)" />
<xsl:if test="position() != last()">
<xsl:text> / </xsl:text>
</xsl:if>
</xsl:for-each>
</combination_name>
</xsl:copy>
</xsl:template>
</xsl:transform>
PHP Script
// LOAD XML AND XSL FILES
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->load('Input.xml');
$xslfile = new DOMDocument('1.0', 'UTF-8');
$xslfile->load('XSLTScript.xsl');
// TRANSFORM XML with XSLT
$proc = new XSLTProcessor;
$proc->importStyleSheet($xslfile);
$newXml = $proc->transformToXML($xml);
// ECHO OUTPUT STRING
echo $newXml;
$xml = new SimpleXMLElement($newXml);
$xpath = $xml->xpath('//combination');
$array = [];
foreach($xpath as $result){
$inner = [];
foreach ($result as $node => $item) {
$inner[$node] = (string)$item;
}
$array[] = $inner;
}
var_dump($array);
Transformed XML
<?xml version="1.0" encoding="UTF-8"?>
<combinations>
<combination>
<id_combination>2289</id_combination>
<quantity>4</quantity>
<unit_price_impact>0.000000</unit_price_impact>
<reference>K10100.1B</reference>
<combination_name>Color: Blue / Size: 1</combination_name>
</combination>
<combination>
<id_combination>2290</id_combination>
<quantity>20</quantity>
<unit_price_impact>0.000000</unit_price_impact>
<reference>K10100.2B</reference>
<combination_name>Color: Blue / Size: 2</combination_name>
</combination>
</combinations>
Array Output
array(2) {
[0]=>
array(5) {
["id_combination"]=>
string(4) "2289"
["quantity"]=>
string(1) "4"
["unit_price_impact"]=>
string(8) "0.000000"
["reference"]=>
string(9) "K10100.1B"
["combination_name"]=>
string(21) "Color: Blue / Size: 1"
}
[1]=>
array(5) {
["id_combination"]=>
string(4) "2290"
["quantity"]=>
string(2) "20"
["unit_price_impact"]=>
string(8) "0.000000"
["reference"]=>
string(9) "K10100.2B"
["combination_name"]=>
string(21) "Color: Blue / Size: 2"
}
}

Colon in xml tag not able to be referenced in php

I need something to either replace the colon, or find a way to work with it. This tag is inside of multiple other tags. This XML that is the problem:
<ns2:Amount>9.99</ns2:Amount>
This is the full xml
<GetMatchingProductForIdResult Id="082686322638" IdType="UPC" status="Success">
<Products>
<Product>
<Identifiers>
<MarketplaceASIN>
<MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
<ASIN>B00TU53O8Q</ASIN>
</MarketplaceASIN>
</Identifiers>
<AttributeSets>
<ns2:ItemAttributes xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd" xml:lang="en-US">
<ns2:Binding>Toy</ns2:Binding>
<ns2:Brand>Rubie's</ns2:Brand>
<ns2:Color>BLACK</ns2:Color>
<ns2:Department>unisex-child</ns2:Department>
<ns2:Feature>Half Helmet mask accessory covers face; one size fits most</ns2:Feature>
<ns2:Feature>Officially licensed Star Wars Episode VII costume accessory; as worn by Kylo Ren in Star Wars Episode VII: The Force Awakens</ns2:Feature>
<ns2:Feature>Helmet has faux battle damage representing a pivotal moment in the movie</ns2:Feature>
<ns2:Feature>Kylo Ren costumes and additional accessories available separately</ns2:Feature>
<ns2:Feature>Rubie's offers costumes and accessories from Star Wars original and prequel trilogies as well as the Clone Wars series; great group and family costume ideas</ns2:Feature>
<ns2:ItemDimensions>
<ns2:Height Units="inches">10.00</ns2:Height>
<ns2:Length Units="inches">10.00</ns2:Length>
<ns2:Width Units="inches">10.00</ns2:Width>
<ns2:Weight Units="pounds">0.13</ns2:Weight>
</ns2:ItemDimensions>
<ns2:IsAdultProduct>false</ns2:IsAdultProduct>
<ns2:Label>Rubies - Domestic</ns2:Label>
<ns2:ListPrice>
<ns2:Amount>9.99</ns2:Amount>
<ns2:CurrencyCode>USD</ns2:CurrencyCode>
</ns2:ListPrice>
<ns2:Manufacturer>Rubies - Domestic</ns2:Manufacturer>
<ns2:ManufacturerMaximumAge Units="months">120.0</ns2:ManufacturerMaximumAge>
<ns2:ManufacturerMinimumAge Units="months">60.0</ns2:ManufacturerMinimumAge>
<ns2:Model>32263</ns2:Model>
<ns2:NumberOfItems>1</ns2:NumberOfItems>
<ns2:PackageDimensions>
<ns2:Height Units="inches">4.00</ns2:Height>
<ns2:Length Units="inches">9.20</ns2:Length>
<ns2:Width Units="inches">8.20</ns2:Width>
<ns2:Weight Units="pounds">0.15</ns2:Weight>
</ns2:PackageDimensions>
<ns2:PackageQuantity>1</ns2:PackageQuantity>
<ns2:PartNumber>32263</ns2:PartNumber>
<ns2:ProductGroup>Toy</ns2:ProductGroup>
<ns2:ProductTypeName>TOYS_AND_GAMES</ns2:ProductTypeName>
<ns2:Publisher>Rubies - Domestic</ns2:Publisher>
<ns2:Size>One Size</ns2:Size>
<ns2:SmallImage>
<ns2:URL>http://ecx.images-amazon.com/images/I/41XuPVJMMkL._SL75_.jpg</ns2:URL>
<ns2:Height Units="pixels">75</ns2:Height>
<ns2:Width Units="pixels">66</ns2:Width>
</ns2:SmallImage>
<ns2:Studio>Rubies - Domestic</ns2:Studio>
<ns2:Title>Star Wars: The Force Awakens Child's Kylo Ren Half Helmet</ns2:Title>
<ns2:Warranty>No Warranty</ns2:Warranty>
</ns2:ItemAttributes>
</AttributeSets>
<Relationships/>
<SalesRankings>
<SalesRank>
<ProductCategoryId>toy_display_on_website</ProductCategoryId>
<Rank>5183</Rank>
</SalesRank>
<SalesRank>
<ProductCategoryId>2229575011</ProductCategoryId>
<Rank>11</Rank>
</SalesRank>
</SalesRankings>
</Product>
</Products>
</GetMatchingProductForIdResult>
I need to have amount = 9.99 in PHP.
Try this with basic PHP:
$subject = "<ns2:Amount>9.99</ns2:Amount>
<ns2:Test>ABCD</ns2:Test>"; // suppose you have two tags
preg_match_all('/<[^:]*:([^>]*)>(.*)<\/[^>]*>/', $subject, $matches); // matching
$i = 1;
$ii = 0;
foreach ($matches as $key => $value) {
$newArr[$matches[$i][$ii]] = $matches[$ii][$ii];
$ii++;
$i++;
}
$result = array_filter($newArr);
foreach($result as $key => $value){
echo $key." = ".$value. "<br/>";
}
Result is:
Amount = 9.99
Test = ABCD
I was able to create a code that let me ignore the namespaces. This is what it looks like.
$Amount = $xml->GetMatchingProductForIdResult[0]->Products->Product->AttributeSets->children('ns2', true)->ItemAttributes->Binding->Amount;

Why Libxml says invalid schema when maxInclusive have 25 or more digits?

Whether the 25 digits are decimal and integers or just integers, DOMDocument::schemaValidate() fires a warning, return false, and libxml_get_errors(); captures the next errors:
PHP snippet:
$DD = new DOMDocument('1.0', 'ISO-8859-1');
$DD -> loadXML('<?xml version ="1.0" encoding="ISO-8859-1"?><a></a>');
libxml_use_internal_errors(true);
$old_libxml_disable_entity_loader = libxml_disable_entity_loader(false);
$DD -> schemaValidate(__DIR__ . '/schemas/schema.xsd'); // WARNING
libxml_disable_entity_loader($old_libxml_disable_entity_loader);
$errors = libxml_get_errors();
foreach ($errors as $error) { // PRINT ERRORS
echo $error -> code . '<br>';
echo $error -> message . '<br>';
}
DOMDocument::schemaValidate() Generated Errors:
Error 1824:
Element '{http://www.w3.org/2001/XMLSchema}maxInclusive':
'9999999999999999999999999' is not a valid value of the
atomic type 'xs:decimal'. in /path/schema.xsd on line X
Error 1717:
Element '{http://www.w3.org/2001/XMLSchema}maxInclusive': The value
'9999999999999999999999999' of the facet does not validate
against the base type '{http://www.w3.org/2001/XMLSchema}decimal'. in
/path/schema.xsd on line X
Valid schema (invalid XML only):
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema
targetNamespace="http://www.lala.com/la"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:la="http://www.lala.com/la"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:simpleType name="AmountType">
<xs:restriction base="xs:decimal">
<xs:totalDigits value="100"/>
<xs:fractionDigits value="20"/>
<xs:maxInclusive value="999999999999999999999999"/><!-- 24 DIGITS -->
</xs:restriction>
</xs:simpleType>
</xs:schema>
Invalid schema: WARNING + Libxml internal errors of invalid schema
<?xml version="1.0" encoding="ISO-8859-1"?>
<xs:schema
targetNamespace="http://www.lala.com/la"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:la="http://www.lala.com/la"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xs:simpleType name="AmountType">
<xs:restriction base="xs:decimal">
<xs:totalDigits value="100"/>
<xs:fractionDigits value="20"/>
<xs:maxInclusive value="9999999999999999999999999"/><!-- 25 DIGITS -->
</xs:restriction>
</xs:simpleType>
</xs:schema>
PHP version: 5.5.20
Libxml version: 2.9.2
According to W3C XML Schema Part 2: Datatypes Second Edition, libxml2 can limit the range of maxInclusive because it is allowed to limit the range of the value space of xs:decimal...
4.3.7 maxInclusive:
[Definition:] maxInclusive is the ·inclusive upper bound· of the
·value space· for a datatype with the ·ordered· property. The value of
maxInclusive ·must· be in the ·value space· of the ·base type·.
3.2.3 decimal
Note: All ·minimally conforming· processors ·must· support decimal
numbers with a minimum of 18 decimal digits (i.e., with a
·totalDigits· of 18). However, ·minimally conforming· processors ·may·
set an application-defined limit on the maximum number of decimal
digits they are prepared to support, in which case that
application-defined maximum number ·must· be clearly documented.

How to print value of SimpleXmlElement Object

I am getting a SimpleXML object back from a server using Guzzle. The response printed as string looks like valid XML. But when I try to get the individual element values, I am getting blank.
Please help me find what the problem is.
My code is here as well as on Viper-7:
<?php
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<RespOrderHistory xmlns="http://www.example.com/testService/xsd/OrderHistoryResponse_v1.xsd" xmlns:typ="http://www.example.com/testService/xsd/Types_v1.xsd">
<OrdersList>
<typ:OrderNumber>638</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-08T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Cancelled</typ:CurrentStatus>
<typ:StatusDate>2014-04-08T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
<OrdersList>
<typ:OrderNumber>638</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-08T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Active</typ:CurrentStatus>
<typ:StatusDate>2014-04-08T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
<OrdersList>
<typ:OrderNumber>638</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-08T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Cancelled</typ:CurrentStatus>
<typ:StatusDate>2014-04-08T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
<OrdersList>
<typ:OrderNumber>638</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-08T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Active</typ:CurrentStatus>
<typ:StatusDate>2014-04-08T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
<OrdersList>
<typ:OrderNumber>638</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-08T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Cancelled</typ:CurrentStatus>
<typ:StatusDate>2014-04-08T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
<OrdersList>
<typ:OrderNumber>638</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-08T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Active</typ:CurrentStatus>
<typ:StatusDate>2014-04-08T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
<OrdersList>
<typ:OrderNumber>638</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-08T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Cancelled</typ:CurrentStatus>
<typ:StatusDate>2014-04-08T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
<OrdersList>
<typ:OrderNumber>638</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-08T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Active</typ:CurrentStatus>
<typ:StatusDate>2014-04-08T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
<OrdersList>
<typ:OrderNumber>638</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-08T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Cancelled</typ:CurrentStatus>
<typ:StatusDate>2014-04-08T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
<OrdersList>
<typ:OrderNumber>638</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-08T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Active</typ:CurrentStatus>
<typ:StatusDate>2014-04-08T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
<OrdersList>
<typ:OrderNumber>138</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-07T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Active</typ:CurrentStatus>
<typ:StatusDate>2014-04-07T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
<OrdersList>
<typ:OrderNumber>133</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-07T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Active</typ:CurrentStatus>
<typ:StatusDate>2014-04-07T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
<OrdersList>
<typ:OrderNumber>128</typ:OrderNumber>
<typ:OrderSubmitDate>2014-04-07T00:00:00.000+05:30</typ:OrderSubmitDate>
<typ:CurrentStatus>Active</typ:CurrentStatus>
<typ:StatusDate>2014-04-07T00:00:00.000+05:30</typ:StatusDate>
</OrdersList>
</RespOrderHistory>';
$sXml = simplexml_load_string ($xml);
foreach($sXml as $order){
echo $order->getName()." ";
print_r($order);
echo "<br/>";
}
?>
Note: By putting your code into your question, you will make it easier for others to help you.
$xml = simplexml_load_string($x); // assume XML in $x
You will need 2 nested loops to iterate. First, you will want to select the <OrdersList>-nodes correctly, see the outer loop.
foreach ($xml->OrdersList as $orders) {
The children of <OrdersList> are namespaced:
$order->OrderNumber doesn't work, but the children()-method does the job:
foreach ($orders->children("typ", TRUE) as $name => $value) {
echo "$name: $value <br />";
}
}
see it working: http://viper-7.com/bS2pEJ
Recommended reading: http://www.php.net/manual/en/simplexmlelement.children.php

Filtering XML file, with PHP

I want to load XML file and then remove all <Charge> where <DispositionDate> is bigger/older then 7 years. Date format is YYYY-MM-DD.
XML example:
<BackgroundReports userId="" password="" account="" >
<BackgroundReportPackage>
<Screenings>
<Screening type="criminal" qualifier="">
<CriminalReport>
<CriminalCase>
<AgencyReference type="Docket">
<IdValue>CR-0870120-09</IdValue>
</AgencyReference>
<Charge>
<ChargeId>
<IdValue>1</IdValue>
</ChargeId>
<ChargeOrComplaint>DUI: HIGHEST RTE OF ALC (BAC .16+) 1ST OFF</ChargeOrComplaint>
<ChargeTypeClassification>unknown</ChargeTypeClassification>
<DispositionDate>2009-04-07</DispositionDate>
</Charge>
<Charge>
<ChargeId>
<IdValue>2</IdValue>
</ChargeId>
<ChargeOrComplaint>CARELESS DRIVING</ChargeOrComplaint>
<ChargeTypeClassification>unknown</ChargeTypeClassification>
<DispositionDate>2010-08-02</DispositionDate>
</Charge>
<Charge>
<ChargeId>
<IdValue>3</IdValue>
</ChargeId>
<ChargeOrComplaint>STATUTE: 475 PC</ChargeOrComplaint>
<ChargeTypeClassification>misdemeanor</ChargeTypeClassification>
<OffenseDate>1988-11-05</OffenseDate>
<Disposition>CONVICTED</Disposition>
<DispositionDate>1988-11-09</DispositionDate>
<DispositionDate>1988-11-05</DispositionDate>
<DispositionDate>1988-11-09</DispositionDate>
</Charge>
</CriminalCase>
</CriminalReport>
</Screening>
</Screenings>
</BackgroundReportPackage>
</BackgroundReports>
I know how to open and close/save file using PHP, I don't know how to delete the part i don't want... If anyone would help me with that I would be extremly thankfull!
You can either use SimpleXML, DOM or XSL for it.
Example XML (shortened for brevity (from Revision 1 of your question)):
$xml = <<< XML
<CriminalCase>
<Charge>
<DispositionDate>1995-12-21</DispositionDate>
</Charge>
<Charge>
<DispositionDate>2010-12-21</DispositionDate>
</Charge>
</CriminalCase>
XML;
With SimpleXml
$sevenYearsAgo = new DateTime('-7 years');
$CriminalCase = new SimpleXmlElement($xml);
for ($i = 0; $i < $CriminalCase->Charge->count(); $i++) {
$dispositionDate = new DateTime($CriminalCase->Charge->DispositionDate);
if ($dispositionDate < $sevenYearsAgo) {
unset($CriminalCase->Charge[$i]);
}
}
echo $CriminalCase->asXml();
With DOM
$dom = new DOMDocument;
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);
$oldCases = $xpath->query(
sprintf(
'//Charge[substring-before(DispositionDate, "-") < %d]',
date('Y', strtotime('-7 years'))
)
);
foreach ($oldCases as $oldCase) {
$oldCase->parentNode->removeChild($oldCase);
}
echo $dom->saveXml();
With XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="http://exslt.org/dates-and-times"
extension-element-prefixes="date">
<xsl:output indent="yes" method="xml"/>
<xsl:template match="/">
<CriminalCase>
<xsl:apply-templates />
</CriminalCase>
</xsl:template>
<xsl:template match="Charge">
<xsl:if test="date:year(DispositionDate) > date:year() - 7">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
and then use this PHP Code to transform it
$doc = new DOMDocument();
$xsl = new XSLTProcessor();
$doc->loadXml($xsl);
$xsl->importStyleSheet($doc);
$doc->loadXml($xml);
echo $xsl->transformToXML($doc);
Here are some tips on how to get started:
You need to parse the XML to something a little easier to work with. PHP has a library called SimpleXML.
Loop through the data and remove the objects which are older than 7 years. To compare dates you have to first convert the dates you got from the XML to something PHP can process as a date. Take a look at strtotime which gives you the timestamp (seconds since 1970, actually 1901 for version > 5.1.0) or DateTime which supports dates before 1970.
To check if the fetched date is older than 7 years ago, you need to (one way) subtract the timestamp with the current timestamp, and see if that value is greater than 7 years in seconds. Or if you use DateTime, you can take a look at DateTime::diff. Remove the objects that you iterate over that are older than 7 years (unset).
To save as XML again, take a look at SimpleXMLElement::asXML
Hope that helps!

Categories