remove Name-Space from xml file and save as new XML - php

this is my link to getting XML File:-XML LINK
this is my code:-
<?php
function convertNodeValueChars($node) {
if ($node->hasChildNodes()) {
foreach ($node->childNodes as $childNode) {
if ($childNode->nodeType == XML_TEXT_NODE) {
$childNode->nodeValue = iconv('utf-8', 'ascii//TRANSLIT', $childNode->nodeValue);
}
convertNodeValueChars($childNode);
}
}
}
$doc = new DOMDocument();
$doc->load('http://services.gisgraphy.com/geoloc/search?lat=13o6&lng=80o12&radius=7000');
convertNodeValueChars($doc->documentElement);
$doc->save('general.xml');
?>
1) i am try to remove ASCII Char to Normal Char
2) want to Remove Name-Space of XML File this is contains name-space<results xmlns="http://gisgraphy.com">
3) want to save as another XML file

first create on simple php file to load xml From the URL:-
<?php
$dom = new DOMDocument();
$dom->load('http://services.gisgraphy.com/geoloc/search?lat=22.298569900000000000&lng=70.794301799999970000&radius=7000', true);
$dom->save('filename.xml');
?>
then create one XSLT file:-
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" version="1.0" encoding="UTF-8" />
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="#* | node()"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
and create one php file to load xml file and implement our xslt file:-
<?php
$sourcedoc->load('filename.xml');
$stylesheet = new DOMDocument();
$stylesheet->load('new4convert.xsl');
// create a new XSLT processor and load the stylesheet
$xsltprocessor = new XSLTProcessor();
$xsltprocessor->importStylesheet($stylesheet);
// save the new xml file
file_put_contents('filename.xml', $xsltprocessor->transformToXML($sourcedoc));
?>
final total code if you want to all in one PHP file:-
<?php
$dom = new DOMDocument();
$dom->load('http://services.gisgraphy.com/geoloc/search?lat=22.298569900000000000&lng=70.794301799999970000&radius=7000', true);
$dom->save('filename.xml');
$sourcedoc = new DOMDocument();
$sourcedoc->load('filename.xml');
$stylesheet = new DOMDocument();
$stylesheet->load('new4convert.xsl');
// create a new XSLT processor and load the stylesheet
$xsltprocessor = new XSLTProcessor();
$xsltprocessor->importStylesheet($stylesheet);
// save the new xml file
file_put_contents('filename.xml', $xsltprocessor->transformToXML($sourcedoc));
?>

Related

How to output in XML version and encoding (PHP)

There is a plugin that forms an XML file for exporting goods. But no matter how hard I try, I can not insert the code <?xml version = "1.0" encoding = "utf-8"?> at the beginning of the line. Unfortunately, it is necessary for the validation of the file. Now produces this way:
<root>
<object>
<objectid></objectid>
<title></title>
<type></type>
...
</object>
<object>...</object>
...
</root>
I'm not a pro on this issue, but I will give only a piece of code in which the problem is possible:
public function onAjaxBTExport()
{
$xml = new SimpleXMLElementExtended('<root/>');
....
$data = $xml->asXML();
file_put_contents(JPATH_SITE.'/data.xml', $data);
header('Content-type: text/xml');
echo $data;
die;
}
class SimpleXMLElementExtended extends SimpleXMLElement
{
private function addCDataToNode(SimpleXMLElement $node, $value = '')
{
if ($domElement = dom_import_simplexml($node))
{
$domOwner = $domElement->ownerDocument;
$domElement->appendChild($domOwner->createCDATASection("{$value}"));
}
}
public function addChildWithCData($name = '', $value = '')
{
$newChild = parent::addChild($name);
if ($value) $this->addCDataToNode($newChild, "{$value}");
return $newChild;
}
public function addCData($value = '')
{
$this->addCDataToNode($this, "{$value}");
}
}
Consider running XSLT (the XML transformation language) using the identity tranform template which copies entire document as is and then explicitly set the omit-xml-declaration to "no". The added benefit of this is pretty printing your output.
To run XSLT 1.0 in PHP, be sure to enable the php-xsl extension in .ini file. Below XSLT is embedded as string but can be parsed from file.
$xml = new SimpleXMLElementExtended('<root/>');
...
$data = $xml->asXML();
// LOAD XML SOURCE
$doc = new DOMDocument;
$doc->loadXML($data);
// LOAD XSLT SOURCE
$xsl = new DOMDocument;
$xsl->loadXML('<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" omit-xml-declaration="no" indent="yes" />
<xsl:strip-space elements="*"/>
<!-- Identity Transform -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:transform>');
// CONFIGURE TRANSFORMER
$proc = new XSLTProcessor;
$proc->importStyleSheet($xsl);
// RUN TRANSFORMATION
$newXML = $proc->transformToXML($doc);
// ECHO TO CONSOLE
header('Content-type: text/xml');
echo $newXML;
// SAVE TO FILE
file_put_contents(JPATH_SITE.'/data.xml', $newXML);

php getimagesize inside xslt

I am quite a bit outside of my comfort zone, working with xslt.
I would like to get the positive ratio between the height and width of an image. But I am having trouble even getting the parameters.
I tried this one:
<xsl:value-of select="php:functionString('getimagesize', image)"/></xsl:element>
But that of course just outputs "Array".
Is there a way to "break" the array similar to $size[1]?
You can create a DOMDocument or document fragment in your PHP code which contains the data you want to return, then you can use XPath on the XSLT side to select the data, here is an example:
<?php
function getDims($url) {
$info = getimagesize($url);
$doc = new DOMDocument();
$root = $doc->appendChild($doc->createElement('dimensions'));
$doc->appendChild($root);
$width = $doc->createElement('width', $info[0]);
$root->appendChild($width);
$height = $doc->createElement('height', $info[1]);
$root->appendChild($height);
return $doc;
}
$xml = <<<'EOB'
<root>
<image>foo.gif</image>
</root>
EOB;
$doc = new DOMDocument();
$doc->loadXML($xml);
$xsl = <<<'EOB'
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:php="http://php.net/xsl"
exclude-result-prefixes="exsl php">
<xsl:output method="html" encoding="utf-8" indent="yes"/>
<xsl:template match="image">
<xsl:variable name="dimensions" select="php:function('getDims', string(.))/*"/>
<img width="{$dimensions/width}" height="{$dimensions/height}" src="{.}"/>
</xsl:template>
</xsl:stylesheet>
EOB;
$xsldoc = new DOMDocument();
$xsldoc->loadXML($xsl);
$proc = new XSLTProcessor();
$proc->registerPHPFunctions();
$proc->importStyleSheet($xsldoc);
echo $proc->transformToXML($doc);
?>

Save and Display a XML file created by transforming values of another XML using Xsl file.

Hi I have a xml file and i'm transforming it's values from xsl file in php. I want to display the new values as an xml. I can get values echoed in the php but when I put the header it gives an error saying junk after element. and I cannot use saveXML() to the returned string.
I need to save these returned information in a new xml file which I have no idea how to do. Please help me in this> thank you in advance.
php file
<?php
//header('Content-Type: text/xml');
$xmlDoc = new DOMDocument('1.0');
$xmlDoc->formatOutput = true;
$xmlDoc->load("rental.xml");
$xslDoc = new DomDocument('1.0');
$xslDoc->load("apartment.xsl");
$proc = new XSLTProcessor;
$proc->importStyleSheet($xslDoc);
$strXml= $proc->transformToXML($xmlDoc);
//echo (toXml($strXml));
echo ($strXml);
//echo $strXml->saveXML();
?>
xsl file
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<xsl:for-each select="//property">
<xsl:element name="rentalProperties">
<xsl:element name="description">
<xsl:value-of select="description"/>
</xsl:element>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
This code will help u to save xml string to a file.
<?php
//header('Content-Type: text/xml');
$xmlDoc = new DOMDocument('1.0');
$xmlDoc->formatOutput = true;
$xmlDoc->load("rental.xml");
$xslDoc = new DomDocument('1.0');
$xslDoc->load("apartment.xsl");
$proc = new XSLTProcessor;
$proc->importStyleSheet($xslDoc);
$strXml= $proc->transformToXML($xmlDoc);
//echo (toXml($strXml));
echo ($proc->transformToXML($xmlDoc));
//$strXml->saveXML();
// Way to parse XML string and save to a file
$convertedXML = simplexml_load_string($strXml);
$convertedXML->saveXML("member.xml");
?>
Cheers.

How to sort a xml file using DOM

I have a xml file structured like
<?xml version="1.0"?>
<library>
<book id="1003">
<title>Jquery MVC</title>
<author>Me</author>
<price>500</price>
</book>
<book id="1001">
<title>Php</title>
<author>Me</author>
<price>600</price>
</book>
<book id="1002">
<title>Where to use IFrame</title>
<author>Me</author>
<price>300</price>
</book>
</library>
In order to sort this xml according to the book id,
after reviewing this method from stackoverflow
i coded like this
$dom = new DOMDocument();
$dom->load('DOM.xml');
$library = $dom->documentElement;
$xpath = new DOMXPath($dom);
$result = $xpath->query('/library/book');
function sort_trees($t1,$t2){
return strcmp($t1['id'], $t2['id']);
}
usort($result, 'sort_trees');
print_r($result);*/
But it gives me an error
Warning: usort() expects parameter 1 to be array, object given in /var/www/html/testphp/phpxml/readxml.php on line 24
The answer you cite is for SimpleXML, but you are using DOMDocument.
If you want to continue to use DOMDocument you need to keep its API in mind.
$dom = new DOMDocument();
$dom->load('DOM.xml');
$xp = new DOMXPath($dom);
$booklist = $xp->query('/library/book');
// Books is a DOMNodeList, not an array.
// This is the reason for your usort() warning.
// Copies DOMNode elements in the DOMNodeList to an array.
$books = iterator_to_array($booklist);
// Second, your sorting function is using the wrong API
// $node['id'] is SimpleXML syntax for attribute access.
// DOMElement uses $node->getAttribute('id');
function sort_by_numeric_id_attr($a, $b)
{
return (int) $a->getAttribute('id') - (int) $b->getAttribute('id');
}
// Now usort()
usort($books, 'sort_by_numeric_id_attr');
// verify:
foreach ($books as $book) {
echo $book->C14N(), "\n";
}
If you need to create a new output document with the nodes sorted, create a new document, import the root element, then import the book nodes in sorted order and add to the document.
$newdoc = new DOMDocument('1.0', 'UTF-8');
$libraries = $newdoc->appendChild($newdoc->importNode($dom->documentElement));
foreach ($books as $book) {
$libraries->appendChild($newdoc->importNode($book, true));
}
echo $newdoc->saveXML();
However, a much better approach is to use XSLT:
<?xml version="1.0" encoding="UTF-8" ?>
<!-- file "sort_by_numeric_id.xsl" -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output encoding="UTF-8" method="xml" />
<xsl:template match="node()|#*">
<xsl:copy><xsl:apply-templates select="node()|#*"/></xsl:copy>
</xsl:template>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="#*"/>
<xsl:apply-templates select="*">
<xsl:sort select="#id" data-type="number"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Then use XSLTProcessor (or xsltproc from the command line):
$xsltdoc = new DOMDocument();
$xsltdoc->load('sort_by_numeric_id.xsl');
$xslt = new XSLTProcessor();
$xslt->importStyleSheet($xsltdoc);
// You can now use $xslt->transformTo*() methods over and over on whatever documents you want
$libraryfiles = array('library1.xml', 'library2.xml');
foreach ($libraryfiles as $lf) {
$doc = new DOMDocument();
$doc->load($lf);
// write the new document
$xslt->transformToUri($doc, 'file://'.preg_replace('/(\.[^.]+)?$/', '-sorted$0', $lf, 1);
unset($doc); // just to save memory
}
(copied over from your duplicate question) This works
$dom = new DOMDocument();
$dom->load('dom.xml');
$xp = new DOMXPath($dom);
$booklist = $xp->query('/library/book');
$books = iterator_to_array($booklist);
function sort_by_numeric_id_attr($a, $b)
{
return (int) $a->getAttribute('id') - (int) $b->getAttribute('id');
}
usort($books, 'sort_by_numeric_id_attr');
$newdom = new DOMDocument("1.0");
$newdom->formatOutput = true;
$root = $newdom->createElement("library");
$newdom->appendChild($root);
foreach ($books as $b) {
$node = $newdom->importNode($b,true);
$root->appendChild($newdom->importNode($b,true));
}
$newdom->save('DOM2.xml');
As you can see, you need to create a new DOMDocument, and add the sorted children to it (via importNode to copy the DOMNodes from one DOMDocument to another).

How to transform a cached XML via XSL?

I have a PHP script that caches a remote XML file. I want to XSL transform it before caching, but don't know how to do this:
<?php
// Set this to your link Id
$linkId = "0oiy8Plr697u3puyJy9VTUWfPrCEvEgJR";
// Set this to a directory that has write permissions
// for this script
$cacheDir = "temp/";
$cachetime = 15 * 60; // 15 minutes
// Do not change anything below this line
// unless you are absolutely sure
$feedUrl="http://mydomain.com/messageService/guestlinkservlet?glId=";
$cachefile = $cacheDir .$linkId.".xml";
header('Content-type: text/xml');
// Send from the cache if $cachetime is not exceeded
if (file_exists($cachefile) && (time() - $cachetime
< filemtime($cachefile)))
{
include($cachefile);
echo "<!-- Cached ".date('jS F Y H:i', filemtime($cachefile))." -->\n";
exit;
}
$contents = file_get_contents($feedUrl . $linkId);
// show the contents of the XML file
echo $contents;
// write it to the cache
$fp = fopen($cachefile, 'w');
fwrite($fp, $contents);
fclose($fp);
?>
This is the XSL string I want to use to transform it:
<xsl:template match="/">
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<xsl:apply-templates select="messageList" />
</Document>
</kml>
</xsl:template>
<xsl:template match="messageList">
<name>My Generated KML</name>
<xsl:apply-templates select="message" />
</xsl:template>
<xsl:template match="message">
<Placemark>
<name><xsl:value-of select="esnName" /></name>
<Point>
<coordinates>
<xsl:value-of select="latitude" />,<xsl:value-of select="longitude" />
</coordinates>
</Point>
</Placemark>
</xsl:template>
I want to actually transform XML input and save/return a KML format. Can someone please help adjust this script? This was given to me and I am a little new to it.
$domOrigin = new DOMDocument('1.0');
$domOrigin->loadXML($contents);
$domXsl = new DOMDocument('1.0');
$domXsl->load('/path/to/stylesheet.xsl',LIBXML_NOCDATA);
$processor = new XSLTProcessor();
$processor->importStylesheet($domXsl);
file_put_contents($cachfile, $processor->transformToXml($domOrigin));
Ill leave it to you to integrate that :-)
Use the XSL extension, there is an example here:
http://www.php.net/manual/en/book.xsl.php#90510
replace your file_get_contents call with:
$XML = new DOMDocument();
$XML->load( $feedUrl . $linkId );
/*
this is the same as the example:
*/
$xslt = new XSLTProcessor();
$XSL = new DOMDocument();
$XSL->load( $xslFile );
$xslt->importStylesheet( $XSL );
then replace the "print" line with file_put_contents( $cachefile, $xslt->transformToXML( $XML ) );
Never use include on anything except a local php source file. It will process the included contents as PHP source. Here is readfile() for other content.
ext/xslt provides an XSLT 1.0 processor with EXSLT support.
I suggest using the cache file as a fallback if here is an error fetch or transforming the external resource also.
$contents = '';
// validate cache
if (
(!$useCache) ||
(!file_exists($chacheFile)) ||
(filemtime($cacheFile) > time() - $expires)
) {
// fetch and transform xml content
$contents = fetchAndTransform($xmlFile, $xsltFile);
if ($useCache) {
// write cache file
file_put_contents($cacheFile, $contents);
}
}
// invalid cache or fetch/transform failure - read cache file
if ($useCache && !$contents) {
// read cache file
$contents = file_get_contents($cacheFile);
}
// output if here is contents
if ($contents) {
} else {
// error handling
}
function fetchAndTransform(string $xmlFile, string $xsltFile): string {
// read xml into DOM
$xmlDocument = new DOMDocument();
$xmlDocument->load($xmlFile);
// read xsl into DOM
$xslDocument = new DOMDocument();
$xslDocument->load($xsltFile);
// initialize xslt processor
$processor = new XSLTProcessor();
// import template
$processor->importStylesheet($xslDocument);
// transform
return $processor->transformToXml($xmlDocument);
}
The namespaces are applied to the nodes while parsing the XSLT (during $xslDocument->load($xsltFile). You need to define the KML namespace (http://www.opengis.net/kml/2.2) on the XSL stylesheet element. So that the parser will put any element without a namespace prefix into it. Otherwise Placemark, name, ... will not be in the KML namespace.
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.opengis.net/kml/2.2">
<xsl:template match="/">
<kml>
<Document>
<xsl:apply-templates select="messageList" />
</Document>
</kml>
</xsl:template>
<xsl:template match="messageList">
<name>My Generated KML</name>
<xsl:apply-templates select="message" />
</xsl:template>
<xsl:template match="message">
<Placemark>
<name><xsl:value-of select="esnName" /></name>
<Point>
<coordinates>
<xsl:value-of select="latitude" />,<xsl:value-of select="longitude" />
</coordinates>
</Point>
</Placemark>
</xsl:template>
</xsl:stylesheet>
XSLT;

Categories