我有一个xml,其中标签可以在元素中包含一个,两个或多个空格和句点(。)。
the xml:
$xml='<?xml version="1.0" encoding="UTF-8"?>
<xmldata>
<SalesHeader>
<DocType>Order</DocType>
<No>1002</No>
<SellToCustomerNo>CustNo</SellToCustomerNo>
<SellToCustomerName>Customer Name</SellToCustomerName>
<SellToCustomerName2 />
<SellToEmail>testemail@aol.com</SellToEmail>
<OrderDate>04/03/13</OrderDate>
<ExtDocNo />
<ShipToName>Customer Ship to</ShipToName>
<ShipToCountry />
<TaxLiable>No</TaxLiable>
<TaxAreaCode />
<RequestedDeliveryDate />
<Shipping Agent>UPS</Shipping Agent>
<Shipping Agent Service>Ground New</Shipping Agent Service>
<Tracking Numbers>123123212,1231231321</Tracking Numbers>
<SalesLine>
<ItemNo.>12-34343-23</ItemNo.>
<Description>Item Description</Description>
<Quantity>1</Quantity>
<UnitPrice>79.00</UnitPrice>
</SalesLine>
<SalesLine>
<ItemNo.>12-34343-23</ItemNo.>
<Description>Item Description</Description>
<Quantity>1</Quantity>
<UnitPrice>79.00</UnitPrice>
</SalesLine>
</SalesHeader>
</xmldata>';
我的代码:
preg_replace(array('/(<\/?)[. ]+(\w*)(\/?>)/','/(<\/?)(\w*)[. ]+(\/?>)/','/(<\/?)(\w*)[. ]+(\w*\/?>)/'),array('$1$2$3','$1$2$3','$1$2$3'),$xml);
当有一个空格或句点时,我只使用preg_match实现了删除,但我想删除句点(。)并用下划线(_)替换空格,即使有多个句点或/和空格也是如此标签和任何位置。
我想得到这个:
change:
<ItemNo.>12-34343-23</ItemNo.>
by:
<ItemNo>12-34343-23</ItemNo>
change:
<Shipping Agent>UPS</Shipping Agent>
by
<Shipping_Agent>UPS</Shipping_Agent>
change:
<Shipping Agent Service>Ground New</Shipping Agent Service>
by
<Shipping_Agent_Service>Ground New</Shipping_Agent_Service>
答案 0 :(得分:2)
我假设您的XML文本具有明确定义的结构。在这种情况下,只有几个无效的元素名称,所有这些都是事先知道的。
解决问题的最佳方法是创建替换列表(错误值=&gt;正确值)并使用str_replace()
修复XML文本,然后再使用simplexml_load_string()
或{{3进行解析}}:
$replacements = array(
'<Shipping Agent>' => '<Shipping_Agent>',
'</Shipping Agent>' => '</Shipping_Agent>',
'<Shipping Agent Service>' => '<Shipping_Agent_Service>',
'</Shipping Agent Service>' => '</Shipping_Agent_Service>',
'<Tracking Numbers>' => '<Tracking_Numbers>',
'</Tracking Numbers>' => '</Tracking_Numbers>',
'<ItemNo.>' => '<ItemNo>',
'</ItemNo.>' => '</ItemNo>',
);
$xml = str_replace(array_keys($replacements), array_values($replacements), $xml);
$result = new \SimpleXMLElement($xml);
regex
- 需要密切关注和广泛测试。xmlcleaner()
快得多,因为它会str_replace()
使用一次调用而xmlcleaner()
多次调用preg_replace()
; SimpleXMLElement
开始时比preg_replace()
慢。答案 1 :(得分:1)
好吧,我自己解决了这个问题,这就是代码:
$xml='<?xml version="1.0" encoding="UTF-8"?>
<xmldata xmlns="http://some.uri.com">
<SalesHeader>
<DocType name="sample">Order</DocType>
<No>1002</No>
<SellToCustomerNo>CustNo</SellToCustomerNo>
<SellToCustomerName>Customer Name</SellToCustomerName>
<SellToCustomerName2 />
<SellToEmail>testemail@aol.com</SellToEmail>
<OrderDate>04/03/13</OrderDate>
<ExtDocNo />
<ShipToName>Customer Ship to</ShipToName>
<ShipToCountry />
<TaxLiable>No</TaxLiable>
<TaxAreaCode />
<RequestedDeliveryDate />
<Shipping Agent>UPS</Shipping Agent>
<Shipping Agent Service>Ground New</Shipping Agent Service>
<Tracking Numbers>123123212,1231231321</Tracking Numbers>
<SalesLine>
<ItemNo.>12-34343-23</ItemNo.>
<Description>Item Description</Description>
<Quantity>1</Quantity>
<UnitPrice>79.00</UnitPrice>
</SalesLine>
<SalesLine>
<ItemNo.>12-34343-23</ItemNo.>
<Description>Item Description</Description>
<Quantity>1</Quantity>
<UnitPrice>79.00</UnitPrice>
</SalesLine>
</SalesHeader>
</xmldata>';
function xmlcleaner($data){
try{
$xml_clean = preg_replace_callback('/(<\/?[^><]+\/?>)/',function($data){
return preg_replace(array('/\./','/\s(?!\/|\>|\w+=\S+)/'),array('','_'),$data[0]);
},$data['xml']);
if(!empty($data['head'])){
$xml_clean = preg_replace('/<\?.+\?>/','',$xml_clean);
$xml_clean = $data['head'].$xml_clean;
}
//now work with SimpleXMLElement
$result = new \SimpleXMLElement((string)$xml_clean);
return $result;
}catch(Exception $e){
return $e->getMessage();
}
}
$xml_clean = xmlcleaner(array(
'xml'=>$xml,
'head'=>'<?xml version="1.0" encoding="utf-8"?>'
));
print('<pre>');
print_r($xml_clean);
答案 2 :(得分:0)
我不认为你会为此获得很好的正则表达式。即使你可以,特别是空间也是令人担忧的。考虑以下有效节点:
<shipper name='baz' />
<shipper name='foo baz bang' />
<shipper name='foo.baz' />
<shipper.name />
与要更正的节点相比:
<ship to name />
<ship. />
我认为您想要做的是提出一个匹配标记的正则表达式,例如
$xmlParts = preg_split("/<[^>]+>/", $xml);
然后您可以遍历$xmlParts
。如果它与同一个正则表达式匹配,则它是一个XML标记,您可以对其进行一些验证:检查它是否应该用_替换空格(因为它们并不表示属性名称或价值),如果。应该完全替换(因为它们不属于属性值)。替换无效字符后,将其附加到新的XML变量中。
如果它与正则表达式不匹配,请假设其内容并将其附加。
尽管如此,如果你能得到任何能够为你提供这些&#34; XML&#34;那么它会变得容易多了。为您提供有效的XML ...