【问题标题】:Removing Double Quotes from JSON String [closed]从 JSON 字符串中删除双引号 [关闭]
【发布时间】:2013-04-18 20:11:19
【问题描述】:

我正在获取一个看起来像这样的 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中?谢谢。

【问题讨论】:

  • 你可以简单地使用str_replace('"0.00"', '0.00', $json)
  • 我认为 str_replace 不会起作用,因为 0.00 值会改变。这些数值是雨量计的降雨量。
  • 所提供的 XSLT 代码包含许多语法和语义错误 -- 请提供您真正使用的代码。
  • @dimitrenovatchev 这是我真正使用的代码。这是我第一次使用 xsl 来转换 XML 文件,所以我可以使用 php 来输出 JSON。我需要 JSON 数据,以便可以使用 JavaScript 和 D3Loader 在我的 Google 地图上绘制标记。其中有哪些错误?它似乎正在输出我需要的东西。
  • @MillerC,您的 XSLT 处理器必须输出错误消息——只需阅读它们。您的文档格式不正确(如 XML),而且 xsl:element 不能有 select 属性。

标签: php xml json xslt


【解决方案1】:

从 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);

http://codepad.viper-7.com/hiWxjH

【讨论】:

  • JSON_NUMERIC_CHECK 确实可以删除 0.00 值周围的双引号,但它也删除了我的“站点”周围的双引号:“770”。这也是一个数值,我需要用引号括起来。
  • @MillerC 然后您必须制作自己的 JSON 格式化程序。要么全有,要么全无。但是,javascript 是松散类型的,您可以循环遍历所有雨值并乘以 1 或 parseInt 以在 JSON.parse 之后在客户端将它们转换为数字。或者另一方面,使用 JSON_NUMERIC_CHECK 并执行 ''+site 将其转换为字符串。
  • "并执行 ''+site 将其转换为字符串。"我将如何在 php 中执行此操作? @jonathankuhn
  • 没关系,JSON_NUMERIC_CHECK 本质上是检查 is_numeric 中的每个值。与数字格式匹配的任何内容都将被视为生成的 json 字符串中的数字。要仅在 php 中执行此操作,您要么必须将站点设为非数字字符串(在其中放入一个字符),要么将下雨数字视为字符串。不过,在客户端,是否有理由说明下雨数字必须是数字而不是字符串? Javascript 是松散类型的,因此数字将在任何表达式中隐式转换为字符串。
  • @MillerC 如果您愿意进行字符串替换,您可以将“rain”键下的值保存到另一个变量,将其替换为要搜索的值,例如“{rain data}” ,将 simplexml 对象转换为 json,使用 JSON_NUMERIC_CHECK 将保存的“rain” xml 转换为 json 并执行 string_replace('"{rain data}"', $rainJSON, $json)
【解决方案2】:

您对SimpleXMLElement 进行json 编码,默认情况下将元素节点值返回为字符串

如果你想改变这种行为,你需要扩展它并改变它为 json 编码对象的方式,例如rain 数组(如果存在)应转换为浮点值:

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);

就是这样。

【讨论】:

  • 我应该在哪里添加 jsonSerialize 函数?我在脚本的开头添加了它,但它不起作用。 @hakre
  • @MillerC:见demo:eval.in/16783 - 接口详情见:php.net/JsonSerializable
  • 感谢您的演示。为什么站点输出中有 NaN? IE:“站点”:“770NaN”而不是“站点”:“770”。 @hakre
  • @MillerC:因为那已经在 XML 中了。与我的 PHP 脚本无关。也许您从中获取 XML 的站点已损坏(在测试时它对我来说也不稳定,因此您可能需要进行一些验证和缓存)
  • 我如何通过使用 url 将来自 rain_data.php 的 XML 数据获取到代码中。该文件不断变化,因此我无法将任何特定值硬编码到 php.ini 文件中。请参阅eval.in/16794 - 不断出错。@hakre 谢谢!
【解决方案3】:

怎么样

<xsl:value-of select="number(RAIN_STRING_HERE)"/>

【讨论】:

  • 这不会影响 OP 正在见证的行为。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-11
相关资源
最近更新 更多