JavaScript中XML转数组:PHP Curl返回XML解析报错问题
问题
我写了一段JavaScript代码把XML转成数组,本地模拟XML测试正常,但传入PHP Curl获取的XML时,出现「Invalid XML」错误。
测试代码
var response = '<?xml version="1.0" encoding="UTF-8"?><root><node1>something</node1></root>' var xmlDoc = $.parseXML( response ); var myArray = getXMLToArray(xmlDoc); alert(myArray['root']['node1']); // 弹出窗口显示文本 "something" function getXMLToArray(xmlDoc){ var thisArray = new Array(); // 检查XML文档 if($(xmlDoc).children().length > 0){ // 遍历找到的每个节点 $(xmlDoc).children().each(function(){ if($(xmlDoc).find(this.nodeName).children().length > 0){ // 如果有子节点,递归获取内部数组 var NextNode = $(xmlDoc).find(this.nodeName); thisArray[this.nodeName] = getXMLToArray(NextNode); } else { // 如果没有子节点,将值存入当前数组 thisArray[this.nodeName] = $(xmlDoc).find(this.nodeName).text(); } }); } return thisArray; }
报错的XML数据
<?xml version="1.0"?> <products><product><id>1</id><order_id>100</order_id><product_id>77</product_id><variant_id>40</variant_id><order_pickup_method_id>0</order_pickup_method_id><order_address_id>1</order_address_id><name>[Sample] Fog Linen Chambray Towel - Beige Stripe</name><name_customer>[Sample] Fog Linen Chambray Towel - Beige Stripe</name_customer><name_merchant>[Sample] Fog Linen Chambray Towel - Beige Stripe</name_merchant><sku>SLCTBS-7A4493EA</sku><upc/><type>physical</type><base_price>49.0000</base_price><price_ex_tax>49.0000</price_ex_tax><price_inc_tax>49.0000</price_inc_tax><price_tax>0.0000</price_tax><base_total>49.0000</base_total><total_ex_tax>49.0000</total_ex_tax><total_inc_tax>49.0000</total_inc_tax><total_tax>0.0000</total_tax><weight>1.0000</weight><width>0.0000</width><height>0.0000</height><depth>0.0000</depth><quantity>1</quantity><base_cost_price>0.0000</base_cost_price><cost_price_inc_tax>0.0000</cost_price_inc_tax><cost_price_ex_tax>0.0000</cost_price_ex_tax><cost_price_tax>0.0000</cost_price_tax><is_refunded>false</is_refunded><quantity_refunded>0</quantity_refunded><refund_amount>0.0000</refund_amount><return_id>0</return_id><wrapping_id>0</wrapping_id><wrapping_name/><base_wrapping_cost>0.0000</base_wrapping_cost><wrapping_cost_ex_tax>0.0000</wrapping_cost_ex_tax><wrapping_cost_inc_tax>0.0000</wrapping_cost_inc_tax><wrapping_cost_tax>0.0000</wrapping_cost_tax><wrapping_message/><quantity_shipped>0</quantity_shipped><event_name>NULL</event_name><event_date/><fixed_shipping_cost>0.0000</fixed_shipping_cost><ebay_item_id/><ebay_transaction_id/><option_set_id>NULL</option_set_id><parent_order_product_id>NULL</parent_order_product_id><is_bundled_product>false</is_bundled_product><bin_picking_number/><external_id>NULL</external_id><fulfillment_source/><brand/><gift_certificate_id>NULL</gift_certificate_id><applied_discounts/><product_options><option><id>1</id><option_id>18</option_id><order_product_id>1</order_product_id><product_option_id>108</product_option_id><display_name>Size</display_name><display_name_customer>Size</display_name_customer><display_name_merchant>Size</display_name_merchant><display_value>XL</display_value><display_value_customer>XL</display_value_customer><display_value_merchant>XL</display_value_merchant><value>72</value><type>Multiple choice</type><name>Apparel sizes</name><display_style>Rectangle</display_style></option><option><id>2</id><option_id>3</option_id><order_product_id>1</order_product_id><product_option_id>109</product_option_id><display_name>Color</display_name><display_name_customer>Color</display_name_customer><display_name_merchant>Color</display_name_merchant><display_value>Red</display_value><display_value_customer>Red</display_value_customer><display_value_merchant>Red</display_value_merchant><value>39</value><type>Swatch</type><name>Colors</name><display_style/></option></product_options><configurable_fields/></product></products>
解决方案
1. 统一编码并验证
本地测试的XML声明了UTF-8编码,但报错的XML仅指定版本未标注编码。在PHP端设置Curl强制使用UTF-8:
$ch = curl_init($url); curl_setopt($ch, CURLOPT_ENCODING, "UTF-8"); // 其他Curl选项 $xml = curl_exec($ch); curl_close($ch);
或者修改PHP返回的XML声明,补充编码:
$xml = preg_replace('/<\?xml version="1.0"\?>/', '<?xml version="1.0" encoding="UTF-8"?>', $xml);
2. 清理特殊字符和BOM
Curl获取的XML可能包含UTF-8 BOM或不可见控制字符,导致解析失败。在PHP端清理:
// 移除UTF-8 BOM $xml = preg_replace('/^\x{FEFF}/u', '', $xml); // 移除控制字符 $xml = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F]/u', '', $xml);
前端也可以做同样处理:
response = response.replace(/^\uFEFF/, '').replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, '');
3. 修复二次转义问题
如果PHP端对XML做了htmlspecialchars类转义,前端需要先反转义:
response = $('<div/>').html(response).text();
4. 处理格式问题
报错的XML包含换行,解析前可先去除换行并修剪空白:
response = response.replace(/\n/g, '').trim();
5. 添加错误捕获排查
在前端添加try-catch,明确解析错误的具体信息:
try { var xmlDoc = $.parseXML(response); var myArray = getXMLToArray(xmlDoc); alert(myArray['products']['product']['id']); } catch (e) { console.error('XML解析错误:', e.message); console.error('原始响应内容:', response); }
内容的提问来源于stack exchange,提问作者Rekha Anguraj
相关产品推荐
相关产品推荐

