Я беру xml-файл, который выглядит так:
<FCDMC><rpt_info created="data generated 04/16/2013 16:45"/><gage_rain id="770" last_rpt="2013-04-16T14:22:11" min_10="0.00" min_30="0.00" hour_1="0.00" hour_3="0.00" hour_6="0.00" day_1="0.00" day_3="0.00" day_7="0.00" name="Tat Momolikot Dam" lat="032:39:04" long="111:55:41"/></FCDMC>
Использование этой таблицы стилей xsl для изменения / изменения документа xml.
<xsl:stylesheet version="1.0"> <xsl:output method="xml" encoding="utf-8" media-type="text/xml" indent="yes"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="rpt_info"> <xsl:element name="meta" select="."> <xsl:for-each select="@created"> <xsl:element name="created" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> </xsl:element> </xsl:template> <xsl:template match="gage_rain"> <xsl:element name="data" select="."> <xsl:for-each select="@id"> <xsl:element name="site" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <xsl:for-each select="@lat"> <xsl:element name="latitude" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <xsl:for-each select="@long"> <xsl:element name="longitude" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <xsl:for-each select="@name"> <xsl:element name="name" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <xsl:for-each select="@last_rpt"> <xsl:element name="last_rpt" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <xsl:for-each select="@min_10"> <xsl:element name="rain" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <xsl:for-each select="@min_30"> <xsl:element name="rain" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <xsl:for-each select="@hour_1"> <xsl:element name="rain" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <xsl:for-each select="@hour_3"> <xsl:element name="rain" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <xsl:for-each select="@hour_6"> <xsl:element name="rain" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <xsl:for-each select="@day_1"> <xsl:element name="rain" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <xsl:for-each select="@day_3"> <xsl:element name="rain" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> <xsl:for-each select="@day_7"> <xsl:element name="rain" select="."> <xsl:value-of select="."/> </xsl:element> </xsl:for-each> </xsl:element> </xsl:template> </xsl:stylesheet>
Чем я использую PHP для вывода нового XML-файла
<?php header('Content-Type: application/xml'); $xml = new DOMDocument; $xml->load('http://alert.fcd.maricopa.gov/alert/Google/xml/fcdmc_alert_rain.xml'); $xsl = new DOMDocument; $xsl->load('http://alert.fcd.maricopa.gov/alert/Google/v3/xslt/fcdmc_alert_rain.xsl'); $proc = new XSLTProcessor; $proc->importStyleSheet($xsl); echo $proc->transformToXML($xml); ?>
и этот php для вывода JSON
<?php $xml = simplexml_load_file('http://alert.fcd.maricopa.gov/alert/Google/v3/php/rainfall_data.php'); $json = json_encode($xml); echo $json; ?>
Это мой текущий выход JSON
{"meta":{"created":"04-18-2013 12:45"},"data":[{"site":"770","latitude":"032:39:04","longitude":"111:55:41","name":"Tat Momolikot Dam","last_rpt":"2013-04-18T11:22:11","rain":["0.00","0.00","0.00","0.00","0.00","0.00","0.00","0.00"]}]}
Это то, что мне нужно для вывода JSON. Мне нужно удалить двойные кавычки (""), которые составляют около 0,00 значений.
{"meta":{"created":"04-18-2013 12:45"},"data":[{"site":"770","latitude":"032:39:04","longitude":"111:55:41","name":"Tat Momolikot Dam","last_rpt":"2013-04-18T11:22:11","rain":[0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00]}]}
Как изменить "rain"
: [строка]?
Я делаю это в xsl? В php? Спасибо.
Начиная с php 5.3.3 вы можете передать флаг JSON_NUMERIC_CHECK
в json_encode, который будет проверять, является ли значение числовым и закодировать строку json с числом вместо строки.
Редактировать:
В моем последнем комментарии, используя замену строки, это сработало бы:
<?php //the json data, since I don't have the original data, I am just decoding the json output. $json = '{"meta":{"created":"04-18-2013 12:45"},"data":[{"site":"770","latitude":"032:39:04","longitude":"111:55:41","name":"Tat Momolikot Dam","last_rpt":"2013-04-18T11:22:11","rain":["0.00","0.00","0.00","0.00","0.00","0.00","0.00","0.00"]}]}'; //decode the json output $array = json_decode($json, 1); //an empty array for rain data $rain = array(); //loop through each data foreach($array['data'] as $k=>$v){ //save the rain data $rain[$k] = $v['rain']; //overwrite the rain data with a simple unique string that can be replaced $array['data'][$k]['rain'] = "{rain data {$k}}"; } //encode the new data with the replacement string $json = json_encode($array); //loop over the rain data replacing the rain data replacement string with a JSON_NUMERIC_CHECK json_encoded rain data foreach($rain as $k=>$v){ //build the search string $search = '"{rain data '.$k.'}"'; //build the replace string $replace = json_encode($v, JSON_NUMERIC_CHECK); //do the replace $json = str_replace($search, $replace, $json); } var_dump($json);
Вы json-encode SimpleXMLElement
который по умолчанию возвращает значения узла элемента как строки .
Если вы хотите изменить это поведение, вам нужно перейти от него и изменить способ кодирования объекта для json, например, массив дождя (если он существует) должен быть преобразован в значения float:
class JsonSerializeXMLElement extends SimpleXMLElement implements JsonSerializable { public function jsonSerialize() { $array = (array) $this; if ($this->rain) { $array['rain'] = array_map('floatval', $array['rain']); } return $array; } }
Тогда ваш скрипт нуждается только в небольшом изменении, чтобы намекнуть на функцию загрузки, чтобы использовать класс с измененным поведением сериализации:
$filename = 'http://alert.fcd.maricopa.gov/alert/Google/v3/php/rainfall_data.php'; $xml = simplexml_load_file($filename, 'JsonSerializeXMLElement'); $json = json_encode($xml);
И это все.
как насчет
<xsl:value-of select="number(RAIN_STRING_HERE)"/>