Чи можна імпортувати файл XML в інший файл XML?
Я маю на увазі, чи є в XML якийсь тег імпорту, який приймає шлях XML як параметр та імпортує XML (для якого вказаний шлях).
Відповіді:
Ви заявляєте сутність таким чином:
<!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>
Кілька посилань, які можуть бути корисними:
XMLResolver
властивість. Якщо властивість XMLResolver не встановлено для вашого об'єкта XMLDocument, тоді воно може не завантажувати зовнішні ресурси. msdn.microsoft.com/en-us/library/5fcwybb2.aspx
Інші відповіді охоплюють 2 найпоширеніші підходи, Xinclude та XML зовнішні сутності. Корпорація Майкрософт має справді чудову інформацію про те, чому слід віддавати перевагу 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 як механізму включення були відомі вже деякий час і фактично спричинили подання пропозиції про включення XML до W3C у 1999 році корпорацією Microsoft та IBM. Пропозиція визначила модель обробки та синтаксис для засобу включення 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>
Ця функція називається включеннями XML (XInclude) . Кілька прикладів:
Рішення Мадса Хансена - це добре, але для успіху у читанні зовнішнього файлу в .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>