как извлечь данные из CDATA - PullRequest
1 голос
/ 17 ноября 2009

Я извлекаю данные из XML, и некоторые теги содержат данные внутри CDATA таким образом

<description><![CDATA[Changes (as compared to 8.17) include:
Features:
    * Added a &#8216;Schema Optimizer&#8217; feature. Based on &#8220;procedure analyse()&#8221; it will propose alterations to data types for a table based on analysis on what data are stored in the table. The feature is available from INFO tab/HTML mode.  Refer to documentation for details.
    * A table can now be added [...]]]>
</description>

Я уже использую preq_match для извлечения данных из тега описания. Как я могу извлечь данные из CDATA?

Ответы [ 3 ]

7 голосов
/ 17 ноября 2009

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

0 голосов
/ 27 марта 2014

@ Павел Минаев прав, оставив опцию регулярного выражения в качестве крайней меры, и для xml всегда используйте анализатор Xml, теперь вы можете найти анализатор xml почти на всех языках. например Я обычно использую DOMDocument для разбора или создания XML в php. Это действительно просто и легко понять специально для таких людей, как я, которые время от времени используют php.

например, вы хотите извлечь CDATA из следующего xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE message SYSTEM "https://www.abcd.com/dtds/AbcdefMessageXmlApi.dtd">
<message id="9002">
  <report>
    <![CDATA[id:50121515075540159 sub:001 text text text text text]]>
  </report>
  <number>353874181931</number>
</message>

Используйте следующий код для извлечения CDATA

$doc = new DOMDocument();
$doc->preserveWhiteSpace = false;

if (TRUE != $doc->loadXML($xml_response)) {

    // log error and / or throw expection or whatever
}

$response_element = $doc->documentElement;

if($response_element->tagName ==  "message"){

    $report_node = $response_element->getElementsByTagName("report");

    if($report_node != null && $report_node->length == 1) {

        $narrative = $report_node->item(0)->textContent;

        $log->debug("CDATA: $narrative");

    } else {

        $log->error("unable to find report tag or multiple report tag found in response xml");
    }

} else {

    $log->error("unexpected root tag (" . $response_element->tagName .") in response xml");
}

после выполнения этой переменной $narrative должен содержаться весь текст, и не беспокойтесь, он не будет содержать некрасивую часть тега CDATA.

Удачного кодирования:)

0 голосов
/ 17 ноября 2009

вы должны использовать simple_xml и xpath, если вам нужно извлечь сложный набор данных.

<?php
$string = <<<XML
<?xml version='1.0'?> 
<document>
 <title>Forty What?</title>
 <from>Joe</from>
 <to>Jane</to>
 <body>
  I know that's the answer -- but what's the question?
 </body>
</document>
XML;

$xml = simplexml_load_string($string);

var_dump($xml);
?>

выдаст вывод, подобный этому:

SimpleXMLElement Object
(
  [title] => Forty What?
  [from] => Joe
  [to] => Jane
  [body] =>
   I know that's the answer -- but what's the question?
)

так что в вашем случае вы бы просто перемещались внутри документа действительно проще, чем reg выражения, не так ли?

...