Я должен встроить весь правильно построенный xml документ в рамках другого xml документа. Однако я избежал бы CDATA (персональное отвращение), и также я хотел бы избежать синтаксического анализатора, который получит целый документ от напрасно тратящего время, проанализировав встроенный xml. Встроенный xml мог быть довольно значительным, и я хотел бы код, который получит целый файл для обработки встроенного xml как произвольных данных.
Идея, которая сразу пришла на ум, состоит в том, чтобы закодировать встроенный xml в base64, или архивировать его. Это звучит хорошо?
Я кодирую в C# между прочим.
Небольшое примечание: я пошел по маршруту base64, и он работает нормально, но дает резкое снижение производительности, особенно при интенсивном использовании. Мы делаем это с фрагментами документов размером до 20 МБ, а после кодирования base64 они могут занимать до 65 МБ (с тегами и данными), даже с архивированием.
Однако более серьезная проблема заключается в том, что кодирование .NET base64 может потреблять до 10 раз больше памяти при выполнении кодирования / декодирования и часто может вызывать исключения OOM, если выполняется повторно и / или выполняется в нескольких потоках.
Кто-то, отвечая на аналогичный вопрос, порекомендовал ProtoBuf в качестве опции, а также Fast InfoSet в качестве другого варианта.
Вы можете преобразовать XML в байтовый массив, а затем преобразовать его в формат binary64. Это позволит вам вложить его в элемент и не использовать CDATA.
Одобренный W3C способ сделать это - XInclude. Существует реализация для .Net по адресу http://mvp-xml.sourceforge.net/xinclude/
В зависимости от того, как вы создаете XML, один из способов - не заботиться об этом и позволить структуре обрабатывать его.
XmlDocument doc = new XmlDocument();
doc.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?><helloworld></helloworld>");
string xml = "<how><are><you reply=\"i am fine\">really</you></are></how>";
doc.GetElementsByTagName("helloworld")[0].InnerText = xml;
Результатом будет что-то вроде строки в HTMLEncoded:
<?xml version="1.0" encoding="utf-8"?>
<helloworld><how><are><you
reply="i am fine">really</you></are></how>
</helloworld>
Похоже, что сериализация является рекомендуемым методом.
Я бы закодировал его вашим любимым способом (например, base64 или HttpServerUtility :: UrlEncode, ...), а затем вставил бы его.
Я использую Комментарии для этого:
[EDITED]
Если встроенный xml-файл с комментариями, замените его другим синтаксисом.
<?xml version="1.0" encoding="iso-8859-1" ?> <xml> <status code="0" msg="" cause="" /> <data> <order type="07" user="none" attrib="..." > <xmlembeded > <!-- <?xml version="1.0" encoding="iso-8859-1" ?> <xml> <status ret="000 "/> <data> <allxml_here /> <!** embedeb comments **> </data> <xml> --> </xmlembeded > </order> <context sessionid="12345678" scriptname="/from/..." attrib="..." /> </data> </xml>
Разве вы не можете использовать XSLT для этого? Возможно, используя xsl: copy или xsl: copy-of? Для этого и нужен XSLT.
Если вам не нужно объявление xml (первая строка документа), просто вставьте корневой элемент (со всеми дочерними элементами ) в дерево другого XML-документа как дочерний элемент существующего элемента. Используйте другое пространство имен для разделения вставленных элементов.