PHP-анализ xml-файла

Я пытаюсь использовать simpleXML для получения данных из http://rates.fxcm.com/RatesXML. С помощью simplexml_load_file() меня были ошибки время от времени, так как этот сайт всегда имеет странные строки / номера до и после файла xml. Пример:

 2000<?xml version="1.0" encoding="UTF-8"?> <Rates> <Rate Symbol="EURUSD"> <Bid>1.27595</Bid> <Ask>1.2762</Ask> <High>1.27748</High> <Low>1.27385</Low> <Direction>-1</Direction> <Last>23:29:11</Last> </Rate> </Rates> 0 

Затем я решил использовать file_get_contents и проанализировать его как строку с simplexml_load_string() , после чего я использую substr() для удаления строк до и после. Однако иногда между этими узлами появляются случайные строки:

 <Rate Symbol="EURTRY"> <Bid>2.29443</Bid> <Ask>2.29562</Ask> <High>2.29841</High> <Low>2.28999</Low> 137b <Direction>1</Direction> <Last>23:29:11</Last> </Rate> 

Мой вопрос в том, есть ли в любом случае я могу справиться со всеми этими случайными строками при работе с любыми регулярными выражениями независимо от того, где они размещены? (подумайте, что это будет лучшая идея, а не связаться с сайтом, чтобы заставить их транслировать соответствующие XML-файлы)

Я считаю, что препроцессор XML с регулярными выражениями может быть столь же плохим, как разбор его .

Но вот замена preg, которая удаляет все символы без пробелов, начиная с начала строки, с конца строки и после закрытия / самозакрывающихся тегов:

 $string = preg_replace( '~ (?| # start of alternation where capturing group count starts from # 1 for each alternative ^[^<]* # match non-< characters at the beginning of the string | # OR [^>]*$ # match non-> characters at the end of the string | # OR ( # start of capturing group $1: closing tag </[^>]++> # match a closing tag; note the possessive quantifier (++); it # suppresses backtracking, which is a convenient optimization, # the following bit is mutually exclusive anyway (this will be # used throughout the regex) \s++ # and the following whitespace ) # end of $1 [^<\s]*+ # match non-<, non-whitespace characters (the "bad" ones) (?: # start subgroup to repeat for more whitespace/non-whitespace # sequences \s++ # match whitespace [^<\s]++ # match at least one "bad" character )* # repeat # note that this will kind of pattern keeps all whitespace # before the first and the last "bad" character | # OR ( # start of capturing group $1: self-closing tag <[^>/]+/> # match a self-closing tag \s++ # and the following whitespace ) [^<]*+(?:\s++[^<\s]++)* # same as before ) # end of alternation ~x', '$1', $input); 

И тогда мы просто записываем закрывающий или самозакрывающийся тег, если он есть.

Одна из причин такого подхода небезопасна в том, что закрывающие или самозакрывающиеся теги могут встречаться внутри комментариев или строк атрибутов. Но я вряд ли могу предложить вам использовать синтаксический анализатор XML, так как ваш синтаксический анализатор XML также не может разобрать XML.