Как встроить XML в XML - PullRequest
       46

Как встроить XML в XML

9 голосов
/ 03 марта 2010

Мне нужно встроить весь правильно сформированный XML-документ в другой XML-документ. Однако я бы предпочел избегать CDATA (личное отвращение), а также я хотел бы избежать парсера, который получит весь документ от потери времени на анализ встроенного XML. Встроенный xml может быть весьма существенным, и я хотел бы, чтобы код, который получит весь файл, рассматривал встроенный xml как произвольные данные.

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

Кстати, я пишу на C #.

Ответы [ 9 ]

5 голосов
/ 03 марта 2010

Вы можете преобразовать XML в байтовый массив, а затем преобразовать его в формат binary64. Это позволит вам вложить его в элемент и не использовать CDATA.

4 голосов
/ 03 марта 2010

W3C-одобренный способ сделать это - XInclude. Существует реализация для .Net по адресу http://mvp -xml.sourceforge.net / xinclude /

3 голосов
/ 03 марта 2010

В зависимости от того, как вы строите 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;

Вывод будет выглядеть как строка, закодированная HTMLE:

<?xml version="1.0" encoding="utf-8"?>
<helloworld>&lt;how&gt;&lt;are&gt;&lt;you
  reply="i am fine"&gt;really&lt;/you&gt;&lt;/are&gt;&lt;/how&gt;
</helloworld>
3 голосов
/ 03 марта 2010

Просто небольшое замечание, я прошел путь base64, и он работает просто отлично, но он идет с жестким снижением производительности, особенно при интенсивном использовании. Мы делаем это с фрагментами документов размером до 20 МБ, и после кодирования base64 они могут занимать более 65 МБ (с тегами и данными), даже с архивированием.

Однако большая проблема заключается в том, что кодирование .NET base64 может занимать до 10 раз больше памяти при выполнении кодирования / декодирования и может часто вызывать исключения OOM, если они выполняются неоднократно и / или выполняются в нескольких потоках.

Кто-то, по схожему вопросу рекомендовал ProtoBuf в качестве опции, а также Fast InfoSet в качестве другой опции.

1 голос
/ 03 марта 2010

Если вам не требуется объявление xml (первая строка документа), просто вставьте корневой элемент (со всеми дочерними элементами) в дерево другого документа xml как дочерний элемент существующего элемента. Используйте другое пространство имен для разделения вставленных элементов.

1 голос
/ 03 марта 2010

Я бы закодировал его вашим любимым способом (например, base64 или HttpServerUtility :: UrlEncode, ...), а затем внедрил его.

0 голосов
/ 03 марта 2010

Разве вы не можете использовать XSLT для этого? Возможно, используя xsl: copy или xsl: copy-of? Вот для чего XSLT.

0 голосов
/ 03 марта 2010

Я использую Комментарии для этого:

<! - ваш текст xml ->

[Изменено]
Если внедренный 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>
0 голосов
/ 03 марта 2010

Кажется, что сериализация является рекомендуемым методом.

...