php с xml внутри cdata

#php #simplexml #cdata

#php #simplexml #cdata

Вопрос:

У меня есть XML-документ с другим XML-документом внутри cdata. Мне нужно прочитать внутренний xml, но в этом xml есть несколько недопустимых символов xml, таких как «amp;», вот почему он заключен в cdata.

Пример:

 <?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Body>
      <outResponse>
         <outReturn>
            <resultData><![CDATA[<?xml version="1.0" encoding="UTF-8"?><DATA><group ID="P12"><FLD NAME="companycode">E173</FLD><FLD NAME="data_link">https://local-services/getkey?amp;api_key=9999</FLD></group></DATA>]]></resultData>
         </outReturn>
      </outResponse>
   </soapenv:Body>
</soapenv:Envelope>
  

В этом примере мне нужно получить значение из тега fld companycode.

Я уже пробовал это с помощью

 $myXML = simplexml_load_string($xmlResponse->xpath('//resultData')[0], 'SimpleXMLElement', LIBXML_NOCDATA);
  

Но это не работает. Все содержимое результирующих данных кодируется (все символы «< >» и amp;, даже символы из узлов), но тогда я не могу загрузить результирующий xml, чтобы получить предполагаемое значение.

Я также безуспешно пытался использовать DOMDocument(). Проблема всегда одна и та же: загрузите xml внутри cdata, чтобы я мог затем получить значение целевого элемента.

Единственный способ, которым я смог достичь этого до сих пор, заключался в том, чтобы работать с содержимым cdata в виде строки и выполнять повторную обработку значения «amp;» для «amp;». Затем я могу загрузить xml и получить значение, но это не кажется хорошей практикой, потому что я могу получить xml с другими символами, которые необходимо кодировать.

Итак, что мне нужно, так это способ загрузить этот xml, не игнорируя cdata, или, другими словами, не игнорируя необходимость автоматической замены некоторых символов.

Есть идеи о том, как этого добиться?

Спасибо

Комментарии:

1. Вы можете легко разделить это на две части: во-первых, чтобы получить строку из этого узла, просто сделайте $brokenXML = (string)$xmlResponse->xpath('//resultData')[0]; Затем игнорируйте, откуда она взялась, и у вас будет классический вопрос «Мне нужно разобрать недопустимый XML».

2. спасибо за ник для редактирования. IMSoP, спасибо за ответ, но xml недействителен только в том случае, если cdata удален. Это то, чего я хочу избежать. Моя цель — понять, есть ли у php способ обработки cdata, как ожидалось.

3. Недопустимый XML — это строка <?xml version="1.0" encoding="UTF-8"?><DATA><group ID="P12"><FLD NAME="companycode">E173</FLD><FLD NAME="data_link">https://local-services/getkey?amp;api_key=9999</FLD></group></DATA> Куда бы вы ни поместили эту строку, она не станет допустимым XML, пока вы не исправите неэкранированный amp;

4. Чтобы привести упрощенный пример, <foo><![CDATA[amp;amp;helloamp;amp;]]></foo> допустим XML, который содержит строку amp;amp;helloamp;amp; . Однако, что бы вы ни делали, это не приведет amp;amp;helloamp;amp; к созданию собственного допустимого XML, поэтому вы не сможете использовать анализатор XML для извлечения строки hello из него.