Czy możemy zaimportować plik XML do innego pliku XML?
Mam na myśli, czy istnieje jakiś znacznik importu w XML, który przyjmuje ścieżkę XML jako parametr i importuje XML (dla którego ścieżka jest podana).
Odpowiedzi:
Deklarujesz jednostkę w ten sposób:
<!ENTITY otherFile SYSTEM "otherFile.xml">
Następnie odwołujesz się do tego w ten sposób:
&otherFile;
Kompletny przykład:
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE doc [
<!ENTITY otherFile SYSTEM "otherFile.xml">
]>
<doc>
<foo>
<bar>&otherFile;</bar>
</foo>
</doc>
Gdy parser XML odczytuje plik, rozszerzy odwołanie do encji i włączy plik XML, do którego się odwołuje, jako część zawartości.
Jeśli plik „otherFile.xml” zawierał: <baz>this is my content</baz>
Następnie XML byłby oceniany i „widziany” przez parser XML jako:
<?xml version="1.0" standalone="no" ?>
<doc>
<foo>
<bar><baz>this is my content</baz></bar>
</foo>
</doc>
Kilka referencji, które mogą być pomocne:
XMLResolver
właściwość jest ustawiona. Jeśli właściwość XMLResolver nie jest ustawiona w obiekcie XMLDocument, może nie ładować zasobów zewnętrznych. msdn.microsoft.com/en-us/library/5fcwybb2.aspx
Pozostałe odpowiedzi dotyczą 2 najczęściej stosowanych podejść, Xinclude i XML jednostek zewnętrznych. Microsoft ma naprawdę świetny opis, dlaczego należy preferować Xinclude, a także kilka przykładowych implementacji. Poniżej przytoczyłem porównanie:
Na http://msdn.microsoft.com/en-us/library/aa302291.aspx
Dlaczego XInclude?
Pierwsze pytanie, które można zadać, brzmi: „Po co używać XInclude zamiast zewnętrznych jednostek XML?” Odpowiedź jest taka, że zewnętrzne encje XML mają szereg dobrze znanych ograniczeń i niewygodnych implikacji, które skutecznie uniemożliwiają im pełnienie funkcji integracji ogólnego przeznaczenia. Konkretnie:
- Zewnętrzna jednostka XML nie może być w pełni niezależnym dokumentem XML - ani samodzielna deklaracja XML, ani deklaracja Doctype nie są dozwolone. Oznacza to, że sama jednostka zewnętrzna XML nie może zawierać innych jednostek zewnętrznych.
- Zewnętrzna jednostka XML musi być dobrze sformułowanym XML (na pierwszy rzut oka nie jest tak źle, ale wyobraź sobie, że chcesz dołączyć przykładowy kod C # do dokumentu XML).
- Niepowodzenie wczytania jednostki zewnętrznej jest błędem krytycznym; jakiekolwiek odzyskiwanie jest surowo zabronione.
- Uwzględnić można tylko cały podmiot zewnętrzny, nie ma możliwości uwzględnienia tylko części dokumentu. -Zewnętrzne jednostki muszą być zadeklarowane w DTD lub wewnętrznym podzbiorze. To otwiera Puszkę Pandory pełną implikacji, takich jak fakt, że element dokumentu musi być nazwany w deklaracji Doctype i że weryfikujący czytelnicy mogą wymagać zdefiniowania pełnego modelu treści dokumentu między innymi w DTD.
Wady stosowania zewnętrznych podmiotów XML jako mechanizmu włączania są znane od jakiegoś czasu i faktycznie dały początek przedłożeniu wniosku XML Inclusion do W3C w 1999 roku przez Microsoft i IBM. We wniosku zdefiniowano model przetwarzania i składnię dla funkcji włączania XML ogólnego przeznaczenia.
Cztery lata później wersja 1.0 XML Includes, znana również jako Xinclude, jest rekomendacją kandydata, co oznacza, że W3C uważa, że została szeroko zweryfikowana i spełnia podstawowe problemy techniczne, które zamierzał rozwiązać, ale nie jest jeszcze pełna rekomendacja.
Inną dobrą witryną, która zawiera różne przykładowe implementacje, jest https://www.xml.com/pub/a/2002/07/31/xinclude.html . Poniżej znajduje się przykład typowego przypadku użycia z ich witryny:
<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>
Ta funkcja nazywa się dołączeniami XML (XInclude) . Kilka przykładów:
Rozwiązanie Madsa Hansena jest dobre, ale pomyślne odczytanie zewnętrznego pliku w .NET 4 zajęło trochę czasu, aby dowiedzieć się, korzystając ze wskazówek w komentarzach na temat resolverów, ProhibitDTD i tak dalej.
Oto jak to się robi:
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>