4

http://rates.fxcm.com/RatesXMLからデータを取得するために simpleXML を使用しようとして いますsimplexml_load_file()が、この Web サイトには常に 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ファイルをブロードキャストしてもらうよりも、その方が良い考えだと思います)

4

1 に答える 1

1

正規表現を使用してXMLを前処理することは、それを解析することと同じくらい悪いかもしれないと私は信じています。

ただし、これは、文字列の先頭、文字列の末尾、およびタグを閉じる/自己閉じる後に、空白以外のすべての文字を削除するpregreplaceです。

$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);

次に、終了タグまたは自己終了タグがある場合はそれを書き戻します。

このアプローチが安全でない理由の1つは、コメントまたは属性文字列内で終了タグまたは自己終了タグが発​​生する可能性があることです。ただし、XMLパーサーもXMLを解析できないため、代わりにXMLパーサーを使用することをお勧めすることはほとんどできません。

于 2012-11-19T08:46:36.683 に答える