while parsing through a XML tree like this:
<vco:ItemDetail>
<cac:Item>
<cbc:Description>ROLLENKERNSATZ 20X12 MM 10,5 GR.</cbc:Description>
<cac:SellersItemIdentification>
<cac:ID>78392636</cac:ID>
</cac:SellersItemIdentification>
<cac:ManufacturersItemIdentification>
<cac:ID>RMS100400370</cac:ID>
<cac:IssuerParty>
<cac:PartyName>
<cbc:Name></cbc:Name>
</cac:PartyName>
</cac:IssuerParty>
</cac:ManufacturersItemIdentification>
</cac:Item>
<vco:Availability>
<vco:Code>available</vco:Code>
</vco:Availability>
</vco:ItemDetail>
I always get a blank space which breaks my CSV structure if cbc:Name is empty, which looks like this:
"ROLLENKERNSATZ 20X12 MM 10,5 GR.";78392636;;RMS100400370;"";available
The "available" string is in a new line so my CSV is not structered any more.
My XPath array looks like this:
$columns = array('Description' => 'string(cac:Item/cbc:Description)',
'SellersItemIdentification' => 'string(cac:Item/cac:SellersItemIdentification/cac:ID)',
'StandardItemIdentification' => 'string(cac:Item/cac:StandardItemIdentification/cac:ID)',
'Availability' => 'string(vco:Availability/vco:Code)',
'Producer' => 'string(cac:Item/cac:ManufacturersItemIdentification/cac:IssuerParty/cac:PartyName/cbc:Name');
Is there any expception or replacement I can handle with like replacing the empty node value with "no producer" or something like this?
Thank you
If the value to use as the 'default' can somehow be made to exist somewhere in your input document, the problem can be solved with a quasi-coalesce like this:
e.g.
<vco:ItemDetail xmlns:vco="x1" xmlns:cac="x2" xmlns:cbc="x3">
<ValueIfNoProducer>No Producer</ValueIfNoProducer>
<cac:Item>
...
Then this Xpath 1.0 will apply a default if the Name element is empty or whitespace:
(cac:Item/cac:ManufacturersItemIdentification/cac:IssuerParty
/cac:PartyName/cbc:Name[normalize-space(.)] | ValueIfNoProducer)[1]
I think the following is possible directly in XPath 2.0, but I stand to be corrected:
(cac:Item/cac:ManufacturersItemIdentification/cac:IssuerParty
/cac:PartyName/cbc:Name[normalize-space(.)] | 'No Producer')[1]
Related
I want to save xml document in mysql database as below:
$_docId= $this->getRequest()->getParam('docId', 0);
$_slmData = '<SLM_form_v2 id="slmform"><group_1_1><section1_1/><name1_1>sdfds</name1_1>
enter code here<localname1_2/><selectcountry_1_3>Algeria</selectcountry_1_3></group_1_1>
enter code here<group_1_2><main_doc/><name_doc1>gdgf gfh f</name_doc1><sex_doc1>Male
</sex_doc1><name_institution_1>fsdgdfg</name_institution_1><address_institution_1>gdgfdgfd
</address_institution_1>....';
$_docMapper = new Model_Mapper_XMLDoc();
$_docModel = new Model_XMLDoc();
$_docModel ->doc_data = Zend_Json::encode($_docData);
if ($_docId != 0) {
$_docModel->id = $_docId;
$_docMapper->update($_docModel->toArray(), 'id = ' . $_docId);
$_action = 'update';
} else {
$_docMapper->insert($_docModel->toArray());
$_lastId = $_docMapper->getAdapter()->lastInsertId(); //gets the id of the last inserted record
$_action = 'add';
}
$this->_helper->json->sendJson(array(
'message' => 'success',
'id' => $_lastId,
'action' => $_action
));
It is stored in the db:
INSERT INTO crpcoreix.tbl_xml_doc (slm_data, web_gis_fk) VALUES ('"<SLM_form_v2 id=\\"slmform\\"><group_1_1><section1_1\\/><name1_1>sdfds<\\/name1_1><localname1_2\\/><selectcountry_1_3>Algeria<\\/selectcountry_1_3><\\/group_1_1><group_1_2><main_doc\\/><name_doc1>gdgf gfh f<\\/name_doc1><sex_doc1>Male<\\/sex_doc1><name_institution_1>fsdgdfg<\\/name_institution_1><address_institution_1>gdgfdgfd gdgf<\\/address_institution_1>...', null);
When I'm trying to read the data from the database and display the encoded xml tags the output miss the first part ("<SLM_form_v2 id=\\"slmform\\"><group_1_1><section1_1\\/><name1_1>...) the first part
Array
(
[id] => 1
[xml_data] => "sdfds<\/name1_1>Algeria<\/selectcountry_1_3>...'
[web_gis_fk] =>
)
Please advice how to fix and if there is a better way to store xml documents in database.
Thanx,
first is first you need to double check your given xml syntax, whether its correct or not.
Zend_Json includes a static function called Zend_Json::fromXml(). so
you would better manage to use it instead of Zend_Json::encode when
you encode XML
This function will generate JSON from a given XML input.
This function takes any arbitrary XML string as an input parameter. It also takes an optional Boolean input parameter to instruct the conversion logic to ignore or not ignore the XML attributes during the conversion process.
If this optional input parameter is not given, then the default behavior is to ignore the XML attributes. This function call is made as shown below:
$jsonContents = Zend_Json::fromXml($xmlStringContents, true);
Give it a try but again check your XML syntax
I have this odd problem, I have to read XML structure stored on a mySQL database, one like this:
<geocercaPoligonal>
<nombreGeocerca>Kennedy</nombreGeocerca>
<longitud>-79.89726930856705</longitud>
<latitud>-2.1599807309506396</latitud>
<longitud>-79.9029341340065</longitud>
<latitud>-2.172760363061884</latitud>
</geocercaPoligonal>
When I get the query on PHP (using PDO Fetch:Assoc) and output the result, it results on this:
' Kennedy -79.89726930856705 -2.1599807309506396 -2.172760363061884 -79.9029341340065 '
All tags are omitted and this leads to error when reading this data, I must get values from specific tags, I get a XML load string
The DB::getRow its a prepare/execute PDO function
$geocerca = DB::getRow('SELECT * FROM GeocercasxUsuario WHERE IdGeocerca = :IdGeocerca', ['IdGeocerca' => $IdGeocerca]);
$infoXML = simplexml_load_string($geocerca['InformacionGeografica']);
//The field from the database with the XML string
It gets this info
SimpleXMLElement::__set_state(array(
'nombreGeocerca' => 'Kennedy',
'longitud' => array(
0 => '-79.89726930856705',
1 => '-2.172760363061884',
),
'latitud' => array(
0 => '-2.1599807309506396',
1 => '-79.9029341340065',
),
))
It doesn't read the XML structure properly, how could I fix this? It's something from PHP or mySQL?
What in particular is not being read properly? The SimpleXML object contains all the data from your XML.
You can convert the object into an array so it is easier to work with as follows:
$json_string = json_encode($infoXML);
$result_array = json_decode($json_string, TRUE);
After trying some things, I switched my select statement to get specific XML data like this:
Instead of
SELECT * FROM GeocercasxUsuario WHERE IdUsuario = n (just for example)
I changed it to
SELECT ExtractValue(InformacionGeografica,'/geocercaPoligonal/latitud') AS Latitud, ExtractValue(InformacionGeografica,'/geocercaPoligonal/longitud') AS Longitud, ...(other fields)... FROM GeocercasxUsuario WHERE IdUsuario = n
This way I get an XML array of the values of each tag, pretty useful if you only want inner values :)
I am trying to use the tablesorter pager plugin with AJAX but run into som problemes (or limitations) when trying to handle the AJAX request in my php backend.
If eg. the table is set up with a default sorting of
sortList: [ [0,1], [1,0] ]
I will get a URL like this on my AJAX request:
page=0&size=50&filter=fcol[6]=batteri&sort=col[0]=1&col[1]=0
In my php back end I do a
$cur_sort = $_GET['sort']
and get
col[0]=1
So the last part is missing - I guess since it contains a & char.
How do I get the entire sort string?
That said how is the string col[0]=1&col[1]=0 best parsed? I need to extract the info that col 0 is to be sorter DESC and col 1 ASC.
You can try this;
parse_str($_SERVER['QUERY_STRING'],$data);
It will parse the url to an array;
Also; you should use empty [] instead of [1] and [0]
See more here: parse_str()
Example:
$str = "page=0&size=50&filter=fcol[6]=batteri&sort=col[0]=1&col[1]=0";
parse_str($str, $output);
echo $output['page']; // echo 0
And to answer your question; it is correct; is echoing col[0]=1 because you are dividing with & see here:
&sort=col[0]=1 & col[1]=0;
An advice; use more names, instead.
You could use
&sort[]=1&sort[]=0;
UPDATE:
To access the last one; you should do, simply;
$_GET['col'][1];
If you want to access, the last number in
$_GET['sort'];
You can do this;
$explode = explode('=',$_GET['sort']);
$end = end($explode);
echo $end; //it will outout 1
If you print your entire query_String, it will print this;
Array
(
[page] => 0
[size] => 50
[filter] => fcol[6]=batteri
[sort] => col[0]=1
[col] => Array
(
[1] => 0
)
)
I'm not sure how the ajaxUrl option is being used, but the output shared in the question doesn't look right.
I really have no idea how the string in the question is showing this format:
&sort=col[0]=1&col[1]=0 (where did sort= come from?)
&filter=fcol[6]=batteri (where did filter= come from?)
If you look at how you can manipulate the ajaxUrl option, you will see this example:
ajaxUrl: "http://mydatabase.com?page={page}&size={size}&{sortList:col}&{filterList:fcol}"
So say you have the following settings:
page = 2
size = 10
sortList is set to [[0,1],[3,0]] (1st column descending sort, 4th column ascending sort)
filters is set as ['','','fred']
The resulting url passed to the server will look like this:
http://mydatabase.com?page=2&size=10&col[0]=1&col[3]=0&fcol[2]=fred
The col part of the {sortList:col} placeholder sets the sorted column name passed to the URL & the fcol part of {filterList:fcol} placeholder sets the filter for the set column. So those are not fixed names.
If the above method for using the ajaxUrl string doesn't suit your needs, you can leave those settings out of the ajaxUrl and instead use the customAjaxUrl option to modify the URL as desired. Here is a simple example (I know this is not a conventional method):
ajaxUrl: "http://mydatabase.com?page={page}&size={size}",
// modify the url after all processing has been applied
customAjaxUrl: function(table, url) {
var config = table.config,
// convert [[0,1],[3,0]] into "0-1-3-0"
sort = [].concat.apply( [], config.sortList ).join('-'),
// convert [ '', '', 'fred' ] into "--fred"
filter = config.lastSearch.join('-');
// send the server the current page
return url += '&sort=' + sort + '&filter=' + filter
}
With the same settings, the resulting URL will now look like this:
http://mydatabase.com?page=2&size=10&sort=0-1-3-0&filter=--fred
This is my own best solution so far, but it's not really elegant:
if (preg_match_all("/[^f]col\[\d+]=\d+/", $_SERVER['QUERY_STRING'], $matches)) {
foreach($matches[0] AS $sortinfo) {
if (preg_match_all("/\d+/", $sortinfo, $matches)) {
if(count($matches[0]) == 2) {
echo "Col: ".$matches[0][0]."<br/>";
echo "Order: ".$matches[0][1]."<br/>";
}
}
}
}
It gives me the info I need
Col: 0
Order: 1
Col: 1
Order: 0
But is clumbsy. Is there a better way?
I use simpleXML to process xml file. It has Cyrillic characters. I also use dom_import_simplexml, importNode and appendChild to copy trees from file to file and place to place.
At the end of processing I do print_r of resulting simpleXmlElement and everything is ok. But I also do asXml('outputfile.xml') and something strange is going on: all cyrillic characters that was not wrapped with CDATA (some tags bodies and all attributes) change to their unicode code.
For example, the output of print_r (just a fragment):
SimpleXMLElement Object ( [#attributes] => Array
( [NAME] => Государственный аппарат и механизм
[COSTYES] => 3.89983579639 [COSTNO] => 0
[ID] => 9 )
[COMMENTYES] => Вы совершенно правы.
[COMMENTNO] => Нет, Вы ошиблись. ) ) )
But in file that asXml generates, i get something like this:
<QUEST NAME="Теория#x434;вухмечей"
style="educ" ID="1">
<DESC><![CDATA[Теория происхождения государства, известная как теория "двух мечей" [2, с.40],
представляет из себя...
]]></DESC>`
I set utf-8 locale everywhere it's possible, googled every combination of words "simplexml, unicode, cyrillic, asXml, etc" but nothing worked.
UPD Looks like some function used does htmlentities(). So, thanks to voitcus, the solution is to use html_entity_decode() as adviced here.
I wonder you might not declare encoding when you imported xml document at first. The following two give you different output.
$simplexml = simplexml_load_string('<QUEST NAME="Государственный" />');
if (!$simplexml) { exit('parse failed'); }
print_r($simplexml->asXml());
$simplexml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8"?><QUEST NAME="Государственный" />');
if (!$simplexml) { exit('parse failed'); }
print_r($simplexml->asXml());
SimpleXMLElement object knows its own encoding from the original xml declaration, and if it was not declared, it generates numerical character references for safety, I guess.
I'm trying to add a server side image uploaded from a user form to a Word document that gets generated using LiveDocx.
My word template looks like this.
«image:photo»
AKA
{ MERGEFIELD image:photo \* MERGEFORMAT }
My php looks like this.
$mailMerge = new Zend_Service_LiveDocx_MailMerge();
$mailMerge->uploadImage($this->logo_path);
$mailMerge->assign('image:photo', $this->logo_path);
I just get a blank area where the image should be. My other merge fields are working properly.
I didn't realize that LiveDocx stores only the name of the file to be referenced. I found this out using:
$mailMerge->listImages();
The format came back like this:
array
0 => array
'filename' => string 'directory_logo.png' (length=18)
'fileSize' => int 12829
'createTime' => int 1352835686
'modifyTime' => int 1352835686
So the template file was fine with this format:
«image:photo»
AKA
{ MERGEFIELD image:photo \* MERGEFORMAT }
But my php needed to look like this:
$mailMerge->uploadImage($this->logo_path);
$mailMerge->assign('image:photo', $this->logo_file);
My full working code looks like this:
$mailMerge = new Zend_Service_LiveDocx_MailMerge();
$mailMerge->setUsername($username)
->setPassword($password);
$mailMerge->setLocalTemplate($template_path . '/service_template.docx');
$mailMerge->uploadImage($this->logo_path);
$mailMerge->assign('image:photo', 'directory_logo.png');
$mailMerge->createDocument();
$document = $mailMerge->retrieveDocument('docx');
file_put_contents($this->config->livedocx->document . '/' . $this->prefs['serverid'] . '/service_directory.docx', $document);
$mailMerge->deleteImage('directory_logo.png');