多级XML API返回结果提取CDATA时丢失Answer的correct属性如何解决
问题原因
你之所以丢失Answer节点的correct属性,是因为SimpleXMLElement对象直接通过json_encode序列化的逻辑存在限制:对于同时包含文本内容和属性的低层级子节点,序列化时会直接将节点转为文本字符串,自动丢弃属性值,只有父层级节点的属性会被保留到@attributes字段下,所以你只能拿到Question的属性,拿不到Answer的属性。
解决方案
方案1(更推荐):直接操作SimpleXML对象,跳过JSON转数组步骤
这个方式不会丢失任何节点属性和内容,性能也更好,代码示例如下:
// 拿到XML对象后不需要转JSON,直接读取内容 $questionObj = $objXmlDocument->Response->Questions->Question[0]; // 读取问题文本 $question_1 = (string)$questionObj['text']; // 遍历所有答案选项 foreach ($questionObj->Answer as $answerItem) { // 获取correct属性值,强制转字符串即可拿到true/false $isCorrect = (string)$answerItem['correct']; // 获取答案文本 $answerText = (string)$answerItem; // 构建你需要的input输入框 echo "<input type='radio' name='question_1' value='".htmlspecialchars($answerText)."' data-correct='{$isCorrect}'> ".htmlspecialchars($answerText)."<br>"; }
方案2:自定义SimpleXML转数组方法,保留所有属性
如果你必须要用到数组格式来处理业务,可以用自定义转换函数替代json_encode+json_decode的逻辑,示例函数如下:
function simplexml_to_array($xmlObject) { $arr = []; // 处理节点属性 foreach ($xmlObject->attributes() as $k => $v) { $arr['@attributes'][$k] = (string)$v; } // 处理子节点 foreach ($xmlObject->children() as $k => $v) { if (count($v) === 0) { $arr[$k][] = [ '@attributes' => iterator_to_array($v->attributes()), 'value' => (string)$v ]; } else { $arr[$k][] = simplexml_to_array($v); } } // 处理当前节点文本内容 $textContent = trim((string)$xmlObject); if ($textContent !== '') { $arr['value'] = $textContent; } return $arr; } // 调用方式 $arrOutput = simplexml_to_array($objXmlDocument); // 后续读取correct属性的方式 foreach ($arrOutput['Response']['Questions']['Question'][0]['Answer'] as $answer) { $isCorrect = $answer['@attributes']['correct']; $answerText = $answer['value']; }
内容的提问来源于stack exchange,提问作者matthew parisi
相关产品推荐
相关产品推荐

