Можем ли мы импортировать XML-файл в другой XML-файл?

84

Можем ли мы импортировать XML-файл в другой XML-файл?

Я имею в виду, есть ли в XML какой-либо тег импорта, который принимает путь XML в качестве параметра и импортирует XML (для которого указан путь).

Сумит
источник

Ответы:

95

Вы можете использовать внешнюю (проанализированную) общую сущность .

Вы объявляете объект следующим образом:

<!ENTITY otherFile SYSTEM "otherFile.xml">

Затем вы ссылаетесь на это так:

&otherFile;

Полный пример:

<?xml version="1.0" standalone="no" ?>
<!DOCTYPE doc [
<!ENTITY otherFile SYSTEM "otherFile.xml">
]>
<doc>
  <foo>
    <bar>&otherFile;</bar>
  </foo>
</doc>

Когда синтаксический анализатор XML читает файл, он расширяет ссылку на объект и включает XML-файл, на который имеется ссылка, как часть содержимого.

Если "otherFile.xml" содержит: <baz>this is my content</baz>

Затем XML будет оцениваться и "рассматриваться" синтаксическим анализатором XML как:

<?xml version="1.0" standalone="no" ?>
<doc>
  <foo>
    <bar><baz>this is my content</baz></bar>
  </foo>
</doc>

Несколько ссылок, которые могут быть полезны:

Мадс Хансен
источник
1
Привет, Мэдс, я застрял в этом, что происходит: когда я просматриваю свой файл main.xml в IE, я получаю текст моего otherFile.xml правильно, но когда я использую ту же концепцию в своем приложении и загружаю свой xml в XMLDocument of .net, то я не получаю текст otherFile.xml вместо этого я получаю все, что написано в main.xml, то есть все <? xml version = "1.0" standalone = "no"?> <! DOCTYPE doc [<! ENTITY otherFile SYSTEM "otherFile.xml">]> <doc> <foo> <bar> & otherFile; </bar> </foo> </doc> можете ли вы сказать мне, если мне нужно сделать что-то еще, чтобы загрузить его в свой xmldocument ???
Sumit
3
Я не очень хорошо знаком с .NET api. Однако вам может потребоваться увидеть, что это XMLResolverсвойство установлено. Если свойство XMLResolver не установлено для вашего объекта XMLDocument, он может не загружать внешние ресурсы. msdn.microsoft.com/en-us/library/5fcwybb2.aspx
Мэдс Хансен,
1
понимают ли это браузеры вроде Chrome?
Alp
4
браузеры могут отключить это по соображениям безопасности для локальных файлов. используйте переключатель --allow-file-access-from-files для chrome или загрузите на хост
premek.v
1
В .NET установите XmlResolver (создав XmlUriResolver по умолчанию) и ProhibitDTD (в false) в XmlReaderSettings, чтобы избежать проблем с разрешениями. По умолчанию политика безопасности Windows / .NET не разрешает загрузку внешних ресурсов.
Иоанн Иисус,
26

Другие ответы охватывают 2 наиболее распространенных подхода: внешние сущности Xinclude и XML. У Microsoft есть действительно отличная статья о том, почему следует предпочесть Xinclude, а также несколько примеров реализации. Я процитировал сравнение ниже:

На http://msdn.microsoft.com/en-us/library/aa302291.aspx

Почему XInclude?

Первый вопрос, который можно задать: «Зачем использовать XInclude вместо внешних сущностей XML?» Ответ заключается в том, что внешние сущности XML имеют ряд хорошо известных ограничений и неудобных последствий, которые фактически мешают им быть универсальным средством включения. В частности:

  • Внешний объект XML не может быть полноценным независимым XML-документом - ни отдельное объявление XML, ни объявление Doctype не допускаются. Это фактически означает, что внешний объект XML не может включать другие внешние объекты.
  • Внешний объект XML должен быть правильно сформированным XML (на первый взгляд это не так уж плохо, но представьте, что вы хотите включить образец кода C # в свой XML-документ).
  • Отказ загрузить внешний объект является фатальной ошибкой; любое восстановление строго запрещено.
  • Может быть включен только весь внешний объект, нет возможности включить только часть документа. -Внешние сущности должны быть объявлены в DTD или внутреннем подмножестве. Это открывает ящик Пандоры, полный последствий, таких как тот факт, что элемент документа должен быть назван в объявлении Doctype, и что проверяющие читатели могут потребовать, чтобы полная модель содержимого документа была определена, среди прочего, в DTD.

Недостатки использования внешних сущностей XML в качестве механизма включения были известны в течение некоторого времени и фактически привели к тому, что в 1999 году Microsoft и IBM подали в W3C предложение о включении XML. В предложении определены модель обработки и синтаксис для универсального средства включения XML.

Четыре года спустя версия 1.0 включений XML, также известная как Xinclude, является кандидатом в рекомендацию, что означает, что W3C считает, что она была широко рассмотрена и удовлетворяет основные технические проблемы, которые он намеревался решить, но еще не является полная рекомендация.

Еще один хороший сайт, который предоставляет множество примеров реализации, - это https://www.xml.com/pub/a/2002/07/31/xinclude.html . Ниже приведен типичный пример использования с их сайта:

<book xmlns:xi="http://www.w3.org/2001/XInclude">

  <title>The Wit and Wisdom of George W. Bush</title>

  <xi:include href="malapropisms.xml"/>

  <xi:include href="mispronunciations.xml"/>

  <xi:include href="madeupwords.xml"/>

</book>
ГолосоватьКофе
источник
1
Это сравнение между внешними сущностями Xinclude и XML, оба из которых являются двумя основными ответами и уже показывают или предоставляют примеры использования. Я почувствовал, что это добавило к обсуждению и было слишком длинным / сложным для комментария. Точно так же вопрос задает «может», а не «как», так что, отвечая на обобщенный вопрос, он направлен на прояснение направленности, которая, как я чувствовал, действительно была целью вопроса. Множество других хороших ссылок на конкретную реализацию. При этом, сказал, спасибо за отзыв. Я скоро дополню его примером.
VoteCoffee 08
Я ценю ваш ответ и уважаю то, что вы пытались решить проблему, добавив пример, но я думаю, что ваш ответ по-прежнему в корне ошибочен. Как правило, при цитировании текста из другого места вы должны включить этот текст в цитату (чтобы было очевидно, что вы не пытаетесь использовать плагиат) и, что более важно, предоставить свое собственное обсуждение выше / ниже цитаты, которая очень четко объясняет, почему вы цитируете этот конкретный текст и как он помогает ответить на вопрос. Если сделаю и то, и другое и прокомментирую снова (чтобы я получил уведомление), я с радостью удалю свой комментарий и отзову свой голос против.
Дэн
Обновлено с блочными цитатами и комментариями
VoteCoffee 09
Это значительно лучший ответ! Проголосовал за и удалил свой первый комментарий, который больше не соответствует действительности. Я оставлю другой комментарий для контекста и, надеюсь, поможет будущим читателям писать лучшие ответы.
Дэн
11

Эта функция называется включением XML (XInclude) . Несколько примеров:

Томаш Нуркевич
источник
Я пробовал с msdn.microsoft.com/en-us/library/aa302291.aspx, но без использования :( Мои Xmls - это main.xml <? Xml version = "1.0"?> <Head> <xi: include href = " import.xml " xmlns: xi = " w3.org/2003/XInclude" > </Head> Imported.xml <? xml version = "1.0"?> <footer> © Contoso Corp, 2003 </footer> и последний xml, который я получаю: <? xml version = "1.0"?> <Head> <xi: include href = " import.xml " xmlns: xi = " w3.org/2003/XInclude " /> </Head> я что-то делаю не так?
Sumit
В Java поддержка XInclude должна быть включена явно. Может быть, ваша библиотека требует такой же подготовки?
Tomasz Nurkiewicz
Я использовал .net для синтаксического анализа XMl, мне удалось импортировать XML с помощью Mads Solution .. спасибо за ваше время ..
Sumit
1
libxml поддерживает это, здорово.
RishiD 05
1
Для Java необходимо добавить следующие строки: DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance (); dbFactory.setXIncludeAware (истина);
Рахул Саху
1

Решение Мэдса Хансена хорошее, но для успешного чтения внешнего файла в .NET 4 потребовалось некоторое время, чтобы выяснить, используя подсказки в комментариях о преобразователях, ProhibitDTD и так далее.

Вот как это делается:

        XmlReaderSettings settings = new XmlReaderSettings();
        settings.DtdProcessing = DtdProcessing.Parse;
        XmlUrlResolver resolver = new XmlUrlResolver();
        resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;
        settings.XmlResolver = resolver;
        var reader = XmlReader.Create("logfile.xml", settings);
        XmlDocument doc = new XmlDocument();
        doc.Load(reader);
        foreach (XmlElement element in doc.SelectNodes("//event"))
        {
            var ch = element.ChildNodes;
            var count = ch.Count;
        }

logfile.xml:

<?xml version="1.0"?>
<!DOCTYPE logfile [
<!ENTITY events    
 SYSTEM "events.txt">
]>
<logfile>
&events;
</logfile>

events.txt:

<event>
    <item1>item1</item1>
    <item2>item2</item2>
</event>
user3717478
источник