Attribute not creating using DomDocument in PHP - php

I am stuck with DomDocument
This thing is working fine, no doubt -
$resource1->appendChild($dom->createAttribute('type'))
->appendChild($dom->createTextnode("webcontent"));
It is adding type="webcontent" to resource node
However when I am using this code its not adding it to it -
$resource1->appendChild($dom->createAttribute('adlcp:scormType'))
->appendChild($dom->createTextnode("sco"));
Expected to generate - adlcp:scormType="sco" <-- Not Working
However If I am creating
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <-- Working
Code -
$manifestNode->appendChild($dom->createAttribute('xmlns:xsi'))
->appendChild($dom->createTextNode("http://www.w3.org/2001/XMLSchema-instance"));
Let me know what I am doing wrong and how do I make it working
EDIT
Error -
XML Parsing Error: prefix not bound to a namespace
Googled same with the keyword - xml parsing error prefix not bound to a namespace php but not much help.

To set an attribute on a node:
$resource1->setAttribute('type', 'webcontent');
To set a namespaced attribute on a node (assuming this is the namespace represented by the "adlcp" prefix):
$resource1->setAttributeNS('http://www.adlnet.org/xsd/adlcp_rootv1p2', 'adlcp:scormType', 'sco');

Related

Access Property of nested namespace in XML document

I need to access the value of an attribute located within a nested namespace in a XML document. Here is a sample of the XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<epp:epp xmlns:epp="urn:ietf:params:xml:ns:epp-1.0">
<epp:response>
<epp:result code="1000">
<epp:msg>Domain Check Command completed successfully</epp:msg>
</epp:result>
<epp:msgQ count="4" id="OTE-EPP-155DF5E824E-1BC86"/>
<epp:resData>
<domain:chkData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:cd>
<domain:name avail="1">example.com</domain:name>
</domain:cd>
</domain:chkData>
</epp:resData>
<epp:trID>
<epp:clTRID>123</epp:clTRID>
<epp:svTRID>456</epp:svTRID>
</epp:trID>
</epp:response>
</epp:epp>
In the above, I need to access the "avail" attribute which from what I can gather is located in a nested namespace domain within the epp namespace.
I am using simplexml_load_string($xml) to access the properties. I am able to access the epp namespace but my lack of XML knowledge is failing me on this one :)
Thank you in advance!
EDIT
As the question is marked as a duplicate I want to clear up that I am looking for a value of a property located within a nested namespace.
I have tried to access the property via xpath but have only received undefined namespace prefix errors:
echo $data->xpath('/domain:name')->attributes()->avail;
echo $data->xpath('/epp:response/epp:resData/domain:chkData/domain:cd/domain:name')->attributes()->avail;
I have also tried the above without the epp namespace but the same result. I know how to get the value from a single namespace but not from a nested namespace.
Another Edit:
I am still struggling. I really cannot get xpath to find the associated namespace element within the xml document. The below code is what I'm trying.
I have tried to also just do a vardump on $sxe->xpath('//d:name')) but get an empty array, indicating no values?
Please can someone help a brother out :)
$sxe = simplexml_load_string($result, "SimpleXMLElement", 0, "epp", true);
$code = $sxe->response->result->attributes()->code;
if ($code == 1000) {
$sxe->registerXPathNamespace('d','ietf:params:xml:ns:domain-1.0');
echo $sxe->xpath('//d:name')->attributes()->avail;
}
exit;
YET ANOTHER EDIT
Following another answer I changed my simplexml_load_string() function declaration and attempted to declare 2 xpath namespaces (feels like the closest I have gotten so far) - I am able to get the value in the epp namespace but still no luck with the domain namespace.
$sxe = simplexml_load_string($result,NULL,NULL,'urn:ietf:params:xml:ns:epp-1.0');
$sxe->registerXPathNamespace('epp', 'ietf:params:xml:ns:epp-1.0');
$sxe->registerXPathNamespace('domain', 'ietf:params:xml:ns:domain-1.0');
$code = $sxe->xpath('//epp:result')[0]->attributes()->code;
if ($code == 1000) {
print_r($sxe->xpath('domain:name'));
print_r($sxe->xpath('//domain:name'));
}
exit;

php simplexml_load_file - not able to see in print_r

I am new to simplexml parser in PHP. I have run the examples that I have found and they work as advertised. I can't get it to work with my program though. I have searched in here for hours.
I have an XML file called core.xml (note that the node tags have colons in):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dc:title>Lecture 3</dc:title>
<dc:creator>John Brown & Greg Smith</dc:creator>
<cp:lastModifiedBy>Greg Smith</cp:lastModifiedBy>
<cp:revision>165</cp:revision>
<dcterms:created xsi:type="dcterms:W3CDTF">2010-02-19T04:37:55Z</dcterms:created>
<dcterms:modified xsi:type="dcterms:W3CDTF">2014-01-30T02:41:30Z</dcterms:modified>
</cp:coreProperties>
I use following code to load it into the parser:
if (file_exists('core.xml')){
echo 'file exists <br>';
$xml_core = simplexml_load_file('core.xml');
print_r($xml_core);
}
else
{
exit('Failed to open core.xml.');
}
The file exists but all I get at the print_r is:
file exists
SimpleXMLElement Object ( )
How do I access the nodes? Other XML files that I have to use are many layers in depth.
Thanks
What you describe as an error pattern in your question is actually correct behaviour and not an error.
If you use print_r (or var_dump for that matter) on a SimpleXMLElement it will only show you some rudimentary information about that object and not the entire content of the XML document.
To see the whole XML, use the asXML() method instead. Alternatively to obtain debug information you can use a library that is specifically aware on how to debug SimpleXMLElement content's like simplexml_debug written by IMSop.
In your specific case, the object shows empty (no object members) because there aren't any nodes in the XML document within the default namespace (see: Namespaces in XML 1.0) that - after the more or less complex rules of SimpleXMLElement to array transitions were applied - would have been passed from the objects internal debug handler to the print_r or var_dump function to be displayed then. So only the class-name is given so that you can see it's an object of a certain class - and has no members:
SimpleXMLElement Object ( )
^ ^ ^
object type | `------ object fields (empty)
|
variable type
How to deal with that? It's very simple: Know the XML (you know it aleady) and obtain the data from it as it's documented:
PHP: Dealing with XML errors - Manual - Shows how you create (load) a SimpleXMLElement in a controlled manner and controlling error conditions.
PHP: Basic SimpleXML usage - Manual - Shows how to access data inside an XML document via the API of SimpleXMLElement.
As your XML element names contain colons, you should be made aware that these are so called XML namespaces. As you've seen differences in the print_r output, you will also see differences in accessing the child elements within that namespace. You have to use the children() method and specify the namespace of which you would like to obtain the child elements. If you use the xpath() method to access elements, you need to register an namespace prefix before you use it on the SimpleXMLElement you call that method on.
Some assorted selection of SimpleXML and XML Namespace related Q&A material here on site:
Parse XML with Namespace using SimpleXML (Feb 2009)
PHP namespace simplexml problems (Jan 2010)
PHP SimpleXML Namespace Problem (May 2011)
Parse XML namespaces with php SimpleXML (May 2013)
You can also obtain this information from the PHP manual, just take a look for namespace related information within the SimpleXMLElement API documentation.
You can use file_get_contents to load XML file.
Try
if(file_exists('core.xml'))
{
echo 'file exists <br>';
$xml_core = file_get_contents('core.xml');
$xml = new SimpleXMLElement($xml_core);
print_r($xml);
}
else
{
exit('Failed to open core.xml.');
}

Error when Querying Parse with PHP

I am trying to use the Parse.com SDK with PHP. I have downloaded and installed the SDK and I have successfully created a test object.
However, when trying to retrieve an object with a basic query using the sample code provided in the Parse docs and when I try to run it I get:
Fatal Error: Class 'ParseQuery' not found in /home/jameshilton/public_html/index.php on line 109
I would have guessed that it is not linking to the SDK properly but everything else is working fine.
Any ideas what I'm doing wrong?
By looking at the code of the class ParseClient in on GitHub I can see that the classes are declared in the namespace parse. So when you need an object from the Parse library you need to select the namespace. This can be done in two ways.
At the top of your file write:
use \parse;
or when instantiating the class:
$query = new \parse\ParseQuery
And remember to make sure the files are included either through an autoloader (composer?) or manually using include or require.
Regards.

How add empty namespace to simpleXML element

In order to simulate XML retrieved from a SOAP web service in a local php test environment version of the web service, I wish to add an empty namespace to an element, just as supplied by the actual web service itself.
But when I add a null string namespace argument to the addChild method, it is not added. Any other value does give me a namespace, but as I said I wish to have an empty one.
So
$xml = new SimpleXMLElement('<cdhead/>');
$nako = $xml -> addChild ('nako', '000', '');
gives me
<cdhead>
<nako>000</nako>
</cdhead>
But I wish to have
<cdhead>
<nako xmlns="">000</nako>
</cdhead>
How can I achieve that?
This problem is because you are using php 5.2. Its a bug and was fixed in the PHP 5.2 series. Here you can view the Bugreport. I've tested using PHP 5.3 and your example works out of the box. This should work in any case:
<?php
$xml = new SimpleXMLElement('<cdhead/>');
$nako = $xml -> addChild ('nako', '000');
$nako->addAttribute('xmlns', '');
echo $nako->saveXml();
It adds the attribute manually if the PHP version is lower than 5.3
UPDATE I tried this with PHP 5.2.17-dotdeb too and it worked out of the box, both
addAttribute
addChild with empty string as namespace

How to enable ORM annotation prefix outside of Symfony2?

I'm converting an old PHP project to the Symfony2 framework. Some of the pages are now handled by my Symfony2 front controller (index.php), but many pages have not yet been converted.
The problem is that, within Symfony, all of my Doctrine entity annotations must begin with the ORM\ prefix, but outside of Symfony, that prefix does not appear to be enabled, and so I get the following error:
Class MyProject\MyBundle\Entity\MyClass is not a valid entity or mapped super class.
I've tried to duplicate whatever magic Symfony does to set this up, including following these instructions [doctrine-project.org], and actually including app/autoload.php entirely into my legacy bootstrap process. But nothing works.
Does anyone know how I can manually replicate whatever it is that Symfony does to enable the ORM\ prefix for my Doctrine annotations?
I got the answer from the Symfony2 Google group. The problem is that the Doctrine configuration shown in the documentation uses SimpleAnnotationReader behind the scenes, but you need regular AnnotationReader to use the ORM\ namespace prefix. I got it to work by replacing this:
$config = new Doctrine\ORM\Configuration();
$driver = $config->newDefaultAnnotationDriver('/path/to/my/entities');
with this:
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
// ...
$config = new Doctrine\ORM\Configuration();
$reader = new AnnotationReader();
$driver = new AnnotationDriver($reader, '/path/to/my/entities');
I ended up with:
Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration($paths, $devMode, null, null, false);`
The 3rd and 4th null arguments are default. The 5th false argument tells it to make a standard AnnotationReader rather than a basic one.
I'm using Doctrine 2.5.6.
Explanation
I found I couldn't get Ian's solution working without calling Doctrine\ORM\Tools\Setup::createAnnotationMetadataConfiguration before making my own config. I was getting this error:
'[Semantical Error] The annotation "#Doctrine\ORM\Mapping\Entity" in class My\Class does not exist, or could not be auto-loaded.'
I was really confused so I took a look at the source code.
It turns out createAnnotationMetadataConfiguration calls Doctrine\ORM\Configuration::newDefaultAnnotationDriver rather than creating the annotation driver directly. This calls AnnotationRegistry::registerFile(__DIR__ . '/Mapping/Driver/DoctrineAnnotations.php'); which seems to be critical. After that, newDefaultAnnotationDriver just creates a new AnnotationDriver().

Categories