首页 > 解决方案 > 使用 PHP 遍历和更新复杂的 Json 文件

问题描述

我知道 PHP 不是 Json 最友好的语言,但我正在尝试做一些简单的事情。我需要遍历一个 Json 文件,修改一些元素并保存它。我正在使用RecursiveIteratorIterator它,它可以很好地遍历数组。我修改了一些元素(翻译它们,效果很好),然后用翻译更新它们。此代码适用于 prsng Json 文件,而无需事先了解其节点。

杰森:

{
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": [
                            "GML",
                            "XML"
                        ]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

这是代码:

$json = json_decode(file_get_contents('file.json'), TRUE);
$jsonIterator = new RecursiveIteratorIterator(
   new RecursiveArrayIterator($json),
   RecursiveIteratorIterator::SELF_FIRST);

foreach ($jsonIterator as $key => $val) {
   if(!is_array($val)) { 
     $xlation = mt($val,$lang, $apikey);  //this works fine
     $json[$key] = $xlation;
     }
 }

file_put_contents('translation.json', json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));

这是生成的文件,其中内容被附加而不是更新。

{
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": [
                            "GML",
                            "XML"
                        ]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    },
    "title": "S",
    "ID": "SGML",
    "SortAs": "SGML",
    "GlossTerm": "Linguaggio di marcatura generalizzato standard",
    "Acronym": "SGML",
    "Abbrev": "ISO 8879: 1986",
    "para": "Un linguaggio di meta-markup, utilizzato per creare linguaggi di markup come DocBook.",
    "0": "GML",
    "1": "XML",
    "GlossSee": "markup"
}

标签: phpjson

解决方案


$json每次都在根变量上设置键,因此它有效地将其展平并覆盖任何可能重新出现的键。您必须以某种方式跟踪嵌套的键级别。

下面是一个没有迭代器的递归示例。我刚刚将 JSON 中的所有值大写,然后将它们小写以模拟您的翻译函数调用。

演示:https ://3v4l.org/c6gWP

function process(array $element): array {
    $result = [];
    foreach ($element as $key => $value) {
        if (is_array($value)) {
            $result[$key] = process($value);  // recurse
        } else {
            $result[$key] = strtolower($value); // simulating "mt" translation function with "strtolower"
        }
    }
    return $result;
}

$json = <<<JSON
{
    "glossary": {
        "title": "EXAMPLE GLOSSARY",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "STANDARD GENERALIZED MARKUP LANGUAGE",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A META-MARKUP LANGUAGE, USED TO CREATE MARKUP LANGUAGES SUCH AS DOCBOOK.",
                        "GlossSeeAlso": [
                            "GML",
                            "XML"
                        ]
                    },
                    "GlossSee": "MARKUP"
                }
            }
        }
    }
}
JSON;

$array = json_decode($json, true);
$result = process($array);
echo json_encode($result, JSON_PRETTY_PRINT);
{
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "s",
            "GlossList": {
                "GlossEntry": {
                    "ID": "sgml",
                    "SortAs": "sgml",
                    "GlossTerm": "standard generalized markup language",
                    "Acronym": "sgml",
                    "Abbrev": "iso 8879:1986",
                    "GlossDef": {
                        "para": "a meta-markup language, used to create markup languages such as docbook.",
                        "GlossSeeAlso": [
                            "gml",
                            "xml"
                        ]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

推荐阅读