我正在尝试将xml转换为json,然后将其转换为xml以测试服务,而我遇到的问题是重复键被错误地表示。
以下有效的XML是起点:
<foo>
<bars>
<bar>
<url>http://url</url>
</bar>
<bar>
<url>http://url</url>
</bar>
</bars>
</foo>
哪个转换为json:
{"bars":{"bar":[{"url":"http:\/\/url"},{"url":"http:\/\/url"}]}}
我看到类似问题的每个解决方案最终都会将生成的xml呈现为:
<bars>
<bar>
<n0>
<url>http://url</url>
</n0>
<n1>
<url>http://url</url>
</n1>
</bar>
</bars>
显然,我需要回到原来的xml。结构非常复杂多变,所以我不能指望一个特定的结构。
有什么想法吗?
答案 0 :(得分:1)
您可以使用php文件处理函数并逐行读取xml文件或固定长度标记名称的字符数,并使用简单的if条件,在文件上打印json字符串。
这可能会有效。
答案 1 :(得分:1)
我已经完成了一些编码和解码XML的函数,第一个将XML源作为SimpleXMLElement并将其转换为数组(注意它不处理属性)但似乎适用于您的测试用例还有一些我尝试过的(这个例子稍微修改了一下XML来检查)。第二个采用相同的数组并将其转换为XML重建的字符串。有很多递归正在进行,但是例程很短,所以希望很容易(ish)跟进......
function xmlToArray ( $base, SimpleXMLElement $node ) {
$nodeName = $node->getName();
$childNodes = $node->children();
if ( count($childNodes) == 0 ) {
$base[ $nodeName ] = (string)$node;
}
else {
$new = [];
foreach ( $childNodes as $newNode ) {
$new[] = xmlToArray($base, $newNode);
}
$base[$nodeName] = count($new)>1?$new:$new[0];
}
return $base;
}
function arrayToXML ( $base ) {
foreach ( $base as $name => $node ) {
$xml = "<{$name}>";
if ( $node instanceof stdClass ){
$xml .= arrayToXML($node);
}
elseif ( is_array($node) ) {
foreach ( $node as $ele ){
$xml .= arrayToXML($ele);
}
}
else {
$xml .= $node;
}
$xml .= "</{$name}>";
}
return $xml;
}
$xml_string = <<< XML
<foo>
<bars>
<bar>
<url>http://url1</url>
</bar>
<bar>
<url>http://url2</url>
</bar>
<url>http://url3</url>
</bars>
</foo>
XML;ToXML ($dec);
echo $target;
ML ($dec);
echo $target;
$source = simplexml_load_string($xml_string);
$xml = xmlToArray([], $source);
$enc = json_encode($xml);
echo $enc.PHP_EOL;
$dec = json_decode($enc);
$target = arrayToXML ($dec);
echo $target;
这最终将JSON和XML输出为......
{"foo":{"bars":[{"bar":{"url":"http:\/\/url1"}},{"bar":{"url":"http:\/\/url2"}},{"url":"http:\/\/url3"}]}}
<foo><bars><bar><url>http://url1</url></bar><bar><url>http://url2</url></bar><url>http://url3</url></bars></foo>
答案 2 :(得分:0)
将JSON转换为XML或XML转换为JSON有许多不同的方法。它们的工作方式各不相同,并且没有一种方法总是最好的。他们都必须在可用性和忠实的往返之间做出某种妥协(例如,你的库已经放弃了外部&#34; foo&#34;元素,因此无法在反向转换中重构)
您可以设计一个任意XML到JSON的映射,允许忠实的往返回到XML,但JSON表示不是特别用户友好的,特别是例如,如果您需要忠实地舍入命名空间
XSLT 3.0顺便说一句:它有一些函数可以将任何JSON输入无损地转换为(相当不友好的词汇表)XML,然后忠实地将结果转换回原始的JSON。你需要与此相反。