#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
из него.