Trước tiên, ngay cả XML là một tập con của SGML một tệp SGML hợp lệ không được là một tệp XML được định dạng tốt. XML nghiêm ngặt hơn và không sử dụng tất cả các tính năng mà SGML cung cấp.
Vì DOMDocument
là XML (chứ không phải SGML), điều này không thực sự tương thích.
Next để vấn đề đó, xin vui lòng xem 2.2 Mở Exchange Headers Financial trong Ofexfin1.doc nó giải thích với bạn rằng
Nội dung của một tập tin Mở Exchange tài chính bao gồm một tập hợp đơn giản của tiêu đề tiếp theo nội dung xác định bởi tiêu đề mà
và thêm vào:
Một dòng trống sau cuối cùng tiêu đề. Sau đó (đối với loại OFXSGML), dữ liệu có thể đọc được SGML bắt đầu bằng thẻ < OFX>.
Vì vậy, hãy tìm dòng trống đầu tiên và ngắt từng dải cho đến khi có. Sau đó tải phần SGML vào DOMDocument bằng cách chuyển đổi SGML vào XML đầu tiên:
$source = fopen('file.ofx', 'r');
if (!$source) {
throw new Exception('Unable to open OFX file.');
}
// skip headers of OFX file
$headers = array();
$charsets = array(
1252 => 'WINDOWS-1251',
);
while(!feof($source)) {
$line = trim(fgets($source));
if ($line === '') {
break;
}
list($header, $value) = explode(':', $line, 2);
$headers[$header] = $value;
}
$buffer = '';
// dead-cheap SGML to XML conversion
// see as well http://www.hanselman.com/blog/PostprocessingAutoClosedSGMLTagsWithTheSGMLReader.aspx
while(!feof($source)) {
$line = trim(fgets($source));
if ($line === '') continue;
$line = iconv($charsets[$headers['CHARSET']], 'UTF-8', $line);
if (substr($line, -1, 1) !== '>') {
list($tag) = explode('>', $line, 2);
$line .= '</' . substr($tag, 1) . '>';
}
$buffer .= $line ."\n";
}
// use DOMDocument with non-standard recover mode
$doc = new DOMDocument();
$doc->recover = true;
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
$save = libxml_use_internal_errors(true);
$doc->loadXML($buffer);
libxml_use_internal_errors($save);
echo $doc->saveXML();
mã Ví dụ này sau đó kết quả đầu ra như sau (tái định dạng) XML đó cũng cho thấy rằng DOMDocument nạp dữ liệu đúng cách:
<?xml version="1.0"?>
<OFX>
<SIGNONMSGSRSV1>
<SONRS>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<DTSERVER>20130331073401</DTSERVER>
<LANGUAGE>SPA</LANGUAGE>
</SONRS>
</SIGNONMSGSRSV1>
<BANKMSGSRSV1>
<STMTTRNRS>
<TRNUID>0</TRNUID>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<STMTRS><CURDEF>COP</CURDEF><BANKACCTFROM> ...</BANKACCTFROM>
</STMTRS>
</STMTTRNRS>
</BANKMSGSRSV1>
</OFX>
Tôi không biết liệu điều này có thể được xác thực đối với DTD hay không. Có lẽ điều này hoạt động. Ngoài ra nếu SGML không được viết bằng các giá trị của một thẻ trên cùng một dòng (và chỉ một phần tử duy nhất trên mỗi dòng là bắt buộc), thì chuyển đổi mong manh này sẽ bị phá vỡ.
Cảm ơn bạn, nó hoạt động. Nó được chuyển đổi thành mảng php với http://www.bin-co.com/php/scripts/xml2array/ –
định dạng có vẻ hơi phẳng. bạn có thể muốn sử dụng biến thể này: http://stackoverflow.com/a/15729905/367456 - đó là một dòng mã. – hakre