Czy możemy zaimportować plik XML do innego pliku XML?

84

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).

Sumit
źródło

Odpowiedzi:

95

Możesz użyć zewnętrznej (przeanalizowanej) jednostki ogólnej .

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:

Mads Hansen
źródło
1
Cześć Mads, utknąłem w tym, co się dzieje, kiedy przeglądam mój plik main.xml w IE, wtedy poprawnie otrzymuję tekst mojego otherFile.xml, ale kiedy używam tej samej koncepcji w mojej aplikacji i ładuję mój plik XML do XMLDocument z .net, to zamiast tego nie otrzymuję tekstu otherFile.xml. Otrzymuję wszystko, co jest napisane w pliku main.xml, czyli wszystko <? xml version = "1.0" standalone = "no"?> <! DOCTYPE doc [<! ENTITY otherFile SYSTEM "otherFile.xml">]> <doc> <foo> <bar> & otherFile; </bar> </foo> </doc> czy możesz mi powiedzieć, czy muszę zrobić coś innego, aby załadować go do mojego xmldocument ???
Sumit,
3
Nie jestem zaznajomiony z interfejsem API .NET. Jednak może być konieczne sprawdzenie, na jaką XMLResolverwł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
Mads Hansen
1
czy przeglądarki takie jak Chrome to rozumieją?
Alp
4
przeglądarki mogą to wyłączyć ze względów bezpieczeństwa plików lokalnych. użyj przełącznika --allow-file-access-from-files dla chrome lub prześlij do hosta
premek.v
1
W .NET ustaw XmlResolver (tworząc domyślny XmlUriResolver) i ProhibitDTD (na false) w XmlReaderSettings, aby uzyskać problemy z uprawnieniami. Domyślnie wygląda na to, że polityka bezpieczeństwa Windows / .NET nie zezwala na ładowanie zasobów zewnętrznych.
John Jesus
26

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>
VoteCoffee
źródło
1
Jest to porównanie między zewnętrznymi jednostkami Xinclude i XML, z których obie są dwiema najważniejszymi odpowiedziami i już pokazują lub podają przykłady użycia. Czułem, że dodało to do dyskusji i było zbyt długie / skomplikowane na komentarz. Podobnie pytanie brzmi „można”, a nie „jak”, więc jeśli chodzi o udzielenie odpowiedzi na uogólnione pytanie, zmierza to do wyjaśnienia kierunku, który moim zdaniem był rzeczywiście celem pytania. Wiele innych dobrych referencji na temat konkretnego wdrożenia. Powiedziałem, że dziękuję za informację zwrotną. Niedługo zaktualizuję go przykładem.
VoteCoffee
Doceniam twoją odpowiedź i szacunek, że próbowałeś rozwiązać problem, dodając przykład, ale myślę, że twoja odpowiedź jest nadal zasadniczo błędna. Ogólnie rzecz biorąc, cytując tekst z innego miejsca, powinieneś zawrzeć ten tekst w cytacie blokowym (aby było oczywiste, że nie próbujesz plagiatować) i, co ważniejsze, przedstawić własną dyskusję powyżej / poniżej cytatu blokowego, która bardzo wyraźnie wyjaśnia, dlaczego zacytowałeś ten konkretny tekst i jak pomaga odpowiedzieć na pytanie. Jeśli zrobię obie te rzeczy i skomentuję ponownie (więc otrzymam powiadomienie), chętnie usunę swój komentarz i wycofam mój głos przeciw.
Dan Bechard,
Zaktualizowany cytatami i komentarzami
VoteCoffee
To znacznie lepsza odpowiedź! Głosowałem za i usunąłem mój pierwszy komentarz, który już nie jest prawdziwy. Drugi komentarz zostawiam dla kontekstu i miejmy nadzieję, że pomogę przyszłym czytelnikom napisać lepsze odpowiedzi.
Dan Bechard
11

Ta funkcja nazywa się dołączeniami XML (XInclude) . Kilka przykładów:

Tomasz Nurkiewicz
źródło
Próbowałem z msdn.microsoft.com/en-us/library/aa302291.aspx, ale bez użycia :( Moje pliki XML to 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> i ostateczny plik XML, jaki otrzymam, to. <? xml version = "1.0"?> <Head> <xi: include href = " Import.xml " xmlns: xi = " w3.org/2003/XInclude " /> </Head> czy robię coś źle?
Sumit,
W Javie obsługa XInclude musi być jawnie włączona. Może Twoja biblioteka wymaga takiego samego przygotowania?
Tomasz Nurkiewicz
Używałem .net do parsowania XMl, udało mi się zaimportować XML przez Mads Solution .. dzięki za
Sumit
1
libxml to obsługuje, super.
RishiD
1
W przypadku języka Java należy dodać poniższe wiersze: DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance (); dbFactory.setXIncludeAware (true);
Rahul Sahu
1

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>
user3717478
źródło