Я работаю над реализацией интерфейса SOAP, которая требует от меня добавления XML в качестве CDATA в запрос SOAP. Моя реализация сделана на C ++, и в моем наборе библиотек у меня есть реализация-оболочка по fastxml, что делает ее более удобной для OO (я не писал эту обертку или определенную часть библиотеки).
Я создаю XML-запрос SOAP-запрос и внутренние XML-структуры отдельно друг от друга в отдельных экземплярах XML-документа. Когда я сконструировал внутреннюю структуру XML, я преобразовал ее в строку и добавил ее в запрос SOAP в качестве узла CDATA.
Дело в том, что когда я печатаю строку, полученную путем преобразования внутреннего XML-документа, я получаю совершенно прекрасную строку. Когда я добавляю эту строку как CDATA в запрос SOAP и преобразовываю ее в строку, поле CDATA искажается.
Скажем, у меня есть внутренняя строка структуры XML следующим образом:
<Events>
<Event>
<ID>29081812</SaeID>
<TerminalID>41</TerminalID>
<EventType>A</EventType>
<ObjectNumber>15</ObjectNumber>
<EventCode>=</EventCode>
<EventSubCode>g</EventSubCode>
<TimeStart>2018-08-27T11:29:27.386407+02:00</TimeStart>
</Event>
</Events>
После добавления его в запрос SOAP и преобразования его в строку получается что-то вроде этого:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SendEventsFromTetra xmlns="some-namespace">
<events>
<![CDATA[<Events>
<Event>
<ID>29▒C
Q▒]
▒]
▒▒/▒▒/nTerminalID>
<EventType>A</EventType>
<ObjectNumber>15</ObjectNumber>
<EventCode>=</EventCode>
<EventSubCode>g</EventSubCode>
<TimeStart>2018-08-27T11:29:27.386407+02:00</TimeStart>
</Event>
</Events>
]]>
</events>
</SendEventsFromTetra>
</soap:Body>
</soap:Envelope>
Дополнительная информация:
Примечание 1: Точка, в которой поле CDATA искажается, не всегда совпадает. Чаще всего он уже управляет им в открывающем элементе <Events>
сразу после объявления узла CDATA.
Примечание 2: Преобразование структур XML в строку использует функцию rapidxml :: print, которая добавляет структуры XML в строковый буфер перед возвратом в виде строки:
void XmlBuilder::Save(std::ostream& out, XmlFormat format) const
{
rapidxml::print(out, doc_, format == XmlFormat::Compact ? rapidxml::print_no_indenting : 0);
}
Примечание 3: Иногда это очень плохо изуродовано:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SendEventsFromTetra xmlns="some-namespace">
<events>
<![CDATA[<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SendEventsFromTetra xmlns="some-namespace">
<events>
<![CDATA[<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<SendEventsFromTetra xmlns="some-namespace">
<events>
<![CDATA[<soap:Envelope xmlns:soap="http://schema]]>
</events>
</SendEventsFromTetra>
</soap:Body>
</soap:Envelope>
Я не знаю, делаю ли я это неправильно или это просто ошибка в rapidxml.