get the value of an XML attribute using php - php

I am attempting to take a value from an attribute and use it in an array to insert it into a MySQL table. My XML file is:
<?xml version="1.0"?>
<GetMatchingProductForIdResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<GetMatchingProductForIdResult Id="9780596515898" IdType="ISBN" status="Success">
<Products xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01" xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd">
<Product>
<Identifiers>
<MarketplaceASIN>
<MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
<ASIN>B0026OR39Y</ASIN>
</MarketplaceASIN>
</Identifiers>
and using php I need to extract out the value of Id in GetMatchingProductForIdResult. So far my code is this:
$parsed_xml = ProductId_xml($isbn);
$isbn13 =(string)$parsed_xml->GetMatchingProductProductForIdResult[0]->attributes();
echo $isbn13['Id']; die;
I am getting no result from the echo statement, even if I change it to print_r or var_dump. I have also tried:
$amazonResult = array(
'isbn' => $parsed_xml->GetMatchingProductProductForIdResult[0]['Id'],
Which yielded no results either. I am not sure where to go from here and any assistance will be greatly appreciated.
EDIT: To clarify this a little bit, the value in Id will change for each record. So what is "9780596515898" this time could be Id="9780596312674" for the next record. I need to know what each one is so I can insert them into the database with the other information I need.

I can access the attributes if I close out the XML - otherwise all it does is throw errors.
You can access all attributes, or individually through simplexml:
$str = <<<XML
<?xml version="1.0"?>
<GetMatchingProductForIdResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<GetMatchingProductForIdResult Id="9780596515898" IdType="ISBN" status="Success">
<Products xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01" xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd">
<Product>
<Identifiers>
<MarketplaceASIN>
<MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
<ASIN>B0026OR39Y</ASIN>
</MarketplaceASIN>
</Identifiers>
</Product>
</Products>
</GetMatchingProductForIdResult>
</GetMatchingProductForIdResponse>
XML;
$xml = simplexml_load_string($str);
foreach($xml->GetMatchingProductForIdResult->attributes() as $a => $b) {
echo $a,'="',$b,"\"\n";
}
// Or access them directly:
echo $xml->GetMatchingProductForIdResult->attributes()->Id;
Outputs:
Id="9780596515898" IdType="ISBN" status="Success" 9780596515898

Related

Php xml to array with namespaces

I've got xml that looks like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<products xmlns="http://domain.dev/schema" xmlns:ns2="http://api.domain.dev/schemas">
<header>
<owner>TEST</owner>
</header>
<brand>
<product brandCode="code">
<sizeGridCode>M</sizeGridCode>
<productCategoryAttributes>
<productCategoryAttribute key="longDescription">TEST</productCategoryAttribute>
</productCategoryAttributes>
<LINES>
<productLine>
<productLineId>ASDF</productLineId>
<brandColourName>GreASDFy</brandColourName>
<colourCodes>
<colourCode>ASDF</colourCode>
</colourCodes>
<composition>
<compositionComponent>
<material/>
</compositionComponent>
</composition>
<articles>
<article>
<articleActivationDate>2017-11-20T16:14:15.159Z</articleActivationDate>
<active>true</active>
<brandArticleId>asdfasdf</brandArticleId>
<ean>asdfasdf</ean>
<id>asdfasdf</id>
<articleMedia>
<media>
<ns2:mediaType>image</ns2:mediaType>
<ns2:mediaURL>default_image</ns2:mediaURL>
<ns2:sortOrder>1</ns2:sortOrder>
</media>
</articleMedia>
<categoryAttributes>
<categoryAttribute key="size">XS</categoryAttribute>
</categoryAttributes>
</article>
</articles>
</productLine>
</LINES>
</product>
</brand>
</products>
When I decode this like this:
$xml = simplexml_load_string(
Storage::get($path),
"SimpleXMLElement", LIBXML_NOCDATA
)->registerXPathNamespace("ns2", "http://api.domain.dev/schemas");
$json = json_encode($xml);
return json_decode($json,TRUE);
I receive everything within an array except the <media> things. Obviously this
is because media has a namespace:
<ns2:mediaType>
How do I make sure I get the ns2:mediaType data aswell? Because right now I get an empty array?
-- EDIT --
When I add registerXPathNamespace it's not working. Please see above the edit.

Getting Status of xml

I am working with the amazon API and I need to check the status of the XML. For example:
<GetMatchingProductForIdResult status="Success" IdType="UPC" Id="082686068055">
or
<GetMatchingProductForIdResult status="ClientError" IdType="UPC" Id="082686068055">
How would I go about writing a code that checks if the status is not "Success"? The XML looks like this:
<GetMatchingProductForIdResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<GetMatchingProductForIdResult status="Success" IdType="UPC" Id="082686068055">
<Products>
<Product>
<Identifiers>
...
</Identifiers>
<AttributeSets>
</AttributeSets>
</Product>
</Products>
</GetMatchingProductForIdResult>
Error:
<GetMatchingProductForIdResult Id="082686035408" IdType="UPC" status="ClientError">
<Error>
<Type>Sender</Type>
<Code>InvalidParameterValue</Code>
<Message>Invalid UPC identifier 082686035408 for marketplace ATVPDKIKX0DER</Message>
</Error>
</GetMatchingProductForIdResult>
PHP Code to retrieve the content:
if(isset($items->Products->Product->AttributeSets->children($namespace['ns2'])->ItemAttributes->ListPrice->Amount)) {
$amount = $items->Products->Product->AttributeSets->children($namespace['ns2'])->ItemAttributes->ListPrice->Amount;
}else{
$amount = '0.00';
}
I was able to create this code to get the ID of the product:
//$xml is an open XML file.
$items=$xml->GetMatchingProductForIdResult;
if(isset($items['Id'])){
$id = $items['Id'];
}else{
$id = 'No Id Found';
}
The first tag stays throughout the whole XML file. The tag closes at the end of the file. I am using SimpleXML to open, and get all of the other data needed from the file, but I always have an error when the tags in <AttributeSets> is not valid. I need to find a way to avoid this problem. Thanks in advance.
In fact, there is many ways to go. But as you want just detect whether a error or success occurr:
<?php
$xmldata = <<<XML
<?xml version='1.0' ?>
<GetMatchingProductForIdResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<GetMatchingProductForIdResult status="Success" IdType="UPC" Id="082686068055">
....
</GetMatchingProductForIdResult>
</GetMatchingProductForIdResponse>
XML;
$xml = new SimpleXmlElement($xmldata);
$items = $xml->GetMatchingProductForIdResult;
$ERROR_FOUND = 'Error' == $items->attributes()->status;
if ($ERROR_FOUND) {
// do something on error, such as return or exit()...
}
// continue xml data parsing

XSLT: adding key based on another key in XML

It is possible with XSLT to check for value and create another key under it?
<url>http://xy.com/380094.jpg</url>
Where 380094 is the <product_code>.
and remove childs, where the available key is No.
<available>No</available> -
Original XML:
<?xml version="1.0"?>
<xml>
<produkt>
<product_code>380094</product_code>
<nazov_produktu>loremipsum</nazov_produktu>
<strucny_popis_produktu></strucny_popis_produktu>
<popis_produktu>loremipsum</popis_produktu>
<znacka>LOREMIPSUM</znacka>
<available>Yes</available>
<mj>ks </mj>
<cena>999</cena>
</produkt>
<produkt>
<product_code>000161</product_code>
<nazov_produktu>loremipsum2</nazov_produktu>
<strucny_popis_produktu></strucny_popis_produktu>
<popis_produktu></popis_produktu>
<znacka>LOREM</znacka>
<available>No</available>
<mj>sad</mj>
<cena>19,90</cena>
</produkt>
</xml>
Example output:
<?xml version="1.0"?>
<xml>
<produkt>
<product_code>380094</product_code>
<url>http://xy.com/380094.jpg</url>
<nazov_produktu>loremipsum</nazov_produktu>
<strucny_popis_produktu></strucny_popis_produktu>
<popis_produktu>loremipsum</popis_produktu>
<znacka>LOREMIPSUM</znacka>
<available>Yes</available>
<mj>ks </mj>
<cena>999</cena>
</produkt>
</xml>
You could try doing a select like
select=produkt[available != 'No']
So if you are in a loop for example
<xsl:for-each select=produkt[available != 'No']>
//do stuff
</xsl:for-each>

PHP SimpleXML add child to each parent repeatedly

I have this kind of XML:
<?xml version="1.0" encoding="utf-8"?>
<data>
<stats>
</stats>
<params>
</params>
<results>
<record id='SJDGH'>
<item>abc</item>
<item>def</item>
<item>ghi</item>
</record>
<record id='OIIO'>
<item>abc</item>
<item>def</item>
<item>ghi</item>
</record>
</results>
</data>
I'm generating a new <item> for every <record> in <results> in a loop:
// $data is SimpleXml objec from XML above
foreach ($data->results->record as $record)
{
$newitem = 'New item!'.time().$record->attributes()->id;
}
Somehow in this loop i need to change the SimpleXML object ($data) to contain new items in every <record>.
is it possible?
I needed a little guessing, but this might what you're looking for:
$records = $data->results->record;
foreach($records as $record)
{
$value = sprintf('New Item! %s / id:%s', time(), $record['id']);
$record->item[] = $value;
}
$data->asXML('php://output');
See it in action.
I think you might want to use addChild.
Check it out here: http://php.net/manual/en/simplexmlelement.addchild.php

extract data from an xml file using php

I know this has been asked before, and I have tried a few of the suggestions, but I am not getting the information from the XML file. I need to get the number of sellers (OfferListingCount condition="Any")from an xml file. Here is the XML:
<?xml version="1.0"?>
<GetCompetitivePricingForASINResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<GetCompetitivePricingForASINResult ASIN="0312479743" status="Success">
<Product xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01" xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd">
<Identifiers>
<MarketplaceASIN>
<MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
<ASIN>0312479743</ASIN>
</MarketplaceASIN>
</Identifiers>
<CompetitivePricing>
<CompetitivePrices>
<CompetitivePrice belongsToRequester="false" condition="Used" subcondition="Good">
<CompetitivePriceId>2</CompetitivePriceId>
<Price>
<LandedPrice>
<CurrencyCode>USD</CurrencyCode>
<Amount>36.23</Amount>
</LandedPrice>
<ListingPrice>
<CurrencyCode>USD</CurrencyCode>
<Amount>36.23</Amount>
</ListingPrice>
<Shipping>
<CurrencyCode>USD</CurrencyCode>
<Amount>0.00</Amount>
</Shipping>
</Price>
</CompetitivePrice>
</CompetitivePrices>
<NumberOfOfferListings>
<OfferListingCount condition="Any">34</OfferListingCount>
<OfferListingCount condition="Used">29</OfferListingCount>
<OfferListingCount condition="New">5</OfferListingCount>
</NumberOfOfferListings>
Here is my UPDATED code for Php:
$priceComp_xml = amazonCompPrice_xml($asin);
$compPricing = $priceComp_xml->xpath('/OfferListingCount[#condition="Any"]');
$priceComp_xml returns the information from the xml file, and I am trying to use the next line to get the information I need. When I run the code, get an empty array.
How do I get this information?
http://php.net/manual/en/function.simplexml-load-file.php
$xml = simplexml_load_file($xml_file);
$output = array();
foreach ($xml as $row => $item_data)
{
// Attributes
$attributes = $item_data->attributes();
Load it up, get the attributes.

Categories