Können wir eine XML-Datei in eine andere XML-Datei importieren?

83

Können wir eine XML-Datei in eine andere XML-Datei importieren?

Ich meine, gibt es ein Import-Tag in XML, das den XML-Pfad als Parameter verwendet und XML importiert (für das der Pfad angegeben ist).

Sumit
quelle

Antworten:

93

Sie können eine externe (analysierte) allgemeine Entität verwenden .

Sie deklarieren die Entität wie folgt:

<!ENTITY otherFile SYSTEM "otherFile.xml">

Dann verweisen Sie darauf wie folgt:

&otherFile;

Ein vollständiges Beispiel:

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

Wenn der XML-Parser die Datei liest, erweitert er die Entitätsreferenz und schließt die referenzierte XML-Datei als Teil des Inhalts ein.

Wenn die "otherFile.xml" enthält: <baz>this is my content</baz>

Dann würde das XML von einem XML-Parser ausgewertet und "gesehen" als:

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

Einige Referenzen, die hilfreich sein könnten:

Mads Hansen
quelle
1
Hallo Mads, ich bin festgefahren, was passiert, wenn ich meine main.xml-Datei im IE ansehe, erhalte ich den Text meiner otherFile.xml richtig, aber wenn ich dasselbe Konzept in meiner Anwendung verwende und meine XML in XMLDocument lade von .net bekomme ich dann nicht den Text von otherFile.xml, sondern erhalte alles, was in main.xml geschrieben ist, das ist alles <? xml version = "1.0" standalone = "no"?> <! DOCTYPE doc [<! ENTITY otherFile SYSTEM "otherFile.xml">]> <doc> <foo> <bar> & otherFile; </ bar> </ foo> </ doc> können Sie mir sagen, ob ich etwas anderes tun muss, um es in mein zu laden xmldocument ???
Sumit
3
Ich bin mit der .NET-API nicht sehr vertraut. Möglicherweise müssen Sie jedoch sehen, auf was die XMLResolverEigenschaft festgelegt ist. Wenn die XMLResolver-Eigenschaft für Ihr XMLDocument-Objekt nicht festgelegt ist, werden möglicherweise keine externen Ressourcen geladen. msdn.microsoft.com/en-us/library/5fcwybb2.aspx
Mads Hansen
1
verstehen Browser wie Chrome das?
Alp
3
Browser können dies aus Sicherheitsgründen für lokale Dateien deaktivieren. Verwenden Sie den Schalter --allow-file-access-from-files für Chrome oder laden Sie ihn auf den Host
hoch
1
Setzen Sie in .NET den XmlResolver (indem Sie einen Standard-XmlUriResolver erstellen) und ProhibitDTD (auf false) in den XmlReaderSettings, um frühere Berechtigungsprobleme zu beheben. Standardmäßig scheint die Windows / .NET-Sicherheitsrichtlinie das Laden externer Ressourcen nicht zuzulassen.
Johannes Jesus
26

Die anderen Antworten beziehen sich auf die beiden gängigsten Ansätze, Xinclude und XML, externe Entitäten. Microsoft hat eine wirklich gute Beschreibung, warum man Xinclude bevorzugen sollte, sowie einige Beispielimplementierungen. Ich habe den Vergleich unten zitiert:

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

Warum XInclude?

Die erste Frage lautet: "Warum XInclude anstelle von externen XML-Entitäten verwenden?" Die Antwort lautet, dass externe XML-Entitäten eine Reihe bekannter Einschränkungen und unbequemer Auswirkungen haben, die effektiv verhindern, dass sie eine allgemeine Einschlussfunktion darstellen. Speziell:

  • Eine externe XML-Entität kann kein vollständig unabhängiges XML-Dokument sein. Weder eine eigenständige XML-Deklaration noch eine Doctype-Deklaration sind zulässig. Dies bedeutet effektiv, dass eine externe XML-Entität selbst keine anderen externen Entitäten enthalten kann.
  • Eine externe XML-Entität muss wohlgeformtes XML sein (auf den ersten Blick nicht so schlecht, aber stellen Sie sich vor, Sie möchten Beispiel-C # -Code in Ihr XML-Dokument aufnehmen).
  • Das Nichtladen einer externen Entität ist ein schwerwiegender Fehler. Jede Wiederherstellung ist strengstens untersagt.
  • Es kann nur die gesamte externe Entität einbezogen werden. Es gibt keine Möglichkeit, nur einen Teil eines Dokuments einzuschließen. -Externe Entitäten müssen in einer DTD oder einer internen Teilmenge deklariert werden. Dies öffnet eine Büchse der Pandora voller Implikationen, z. B. die Tatsache, dass das Dokumentelement in der Doctype-Deklaration benannt werden muss und dass für die Validierung von Lesern unter anderem das vollständige Inhaltsmodell des Dokuments in der DTD definiert werden muss.

Die Mängel bei der Verwendung externer XML-Entitäten als Einschlussmechanismus sind seit einiger Zeit bekannt und haben tatsächlich dazu geführt, dass Microsoft und IBM 1999 den XML-Einschlussvorschlag beim W3C eingereicht haben. Der Vorschlag definierte ein Verarbeitungsmodell und eine Syntax für eine universelle XML-Einschlussfunktion.

Vier Jahre später ist Version 1.0 der XML-Einschlüsse, auch als Xinclude bekannt, eine Kandidatenempfehlung. Dies bedeutet, dass das W3C der Ansicht ist, dass es umfassend überprüft wurde und die grundlegenden technischen Probleme erfüllt, die es lösen wollte, aber noch nicht erfüllt ist volle Empfehlung.

Eine weitere gute Website mit einer Vielzahl von Beispielimplementierungen ist https://www.xml.com/pub/a/2002/07/31/xinclude.html . Im Folgenden finden Sie ein Beispiel für einen allgemeinen Anwendungsfall auf ihrer Website:

<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
quelle
1
Es handelt sich um einen Vergleich zwischen externen Xinclude- und XML-Entitäten, die beide die beiden wichtigsten Antworten sind und bereits Anwendungsbeispiele zeigen oder bereitstellen. Ich fand, dass es der Diskussion hinzugefügt wurde und zu lang / kompliziert für einen Kommentar war. Ebenso fragt die Frage "kann" und nicht "wie". Was die Beantwortung einer verallgemeinerten Frage betrifft, so geht dies zur Klärung der Richtwirkung, die meiner Meinung nach wirklich die Absicht der Frage war. Viele andere gute Referenzen zur spezifischen Implementierung. Trotzdem danke ich Ihnen für das Feedback. Ich aktualisiere es in Kürze mit einem Beispiel.
VoteCoffee
Ich schätze Ihre Antwort und Ihren Respekt, dass Sie versucht haben, das Problem durch Hinzufügen eines Beispiels zu lösen, aber ich denke, Ihre Antwort ist immer noch grundlegend fehlerhaft. Wenn Sie Text von einer anderen Stelle zitieren, sollten Sie diesen Text in ein Blockzitat aufnehmen (damit Sie offensichtlich nicht versuchen, ihn zu plagiieren) und, was noch wichtiger ist, über / unter dem Blockzitat eine eigene Diskussion führen, die sehr deutlich erklärt, warum Sie zitiert haben diesen bestimmten Text und wie er hilft, die Frage zu beantworten. Wenn Sie beides tun und erneut kommentieren (damit ich benachrichtigt werde), werde ich meinen Kommentar gerne löschen und meine Ablehnung zurückziehen.
Dan Bechard
Aktualisiert mit
Blockzitaten
Dies ist eine deutlich bessere Antwort! Mein erster Kommentar, der nicht mehr wahr ist, wurde aktualisiert und gelöscht. Ich werde den anderen Kommentar für den Kontext hinterlassen und hoffentlich zukünftigen Lesern helfen, bessere Antworten zu schreiben.
Dan Bechard
11

Diese Funktion wird als XML-Einschlüsse (XInclude) bezeichnet . Einige Beispiele:

Tomasz Nurkiewicz
quelle
Ich habe es mit msdn.microsoft.com/en-us/library/aa302291.aspx ausprobiert, aber ohne Verwendung :( Meine Xmls sind main.xml <? Xml version = "1.0"?> <Head> <xi: include href = "importiert.xml" xmlns: xi = " w3.org/2003/XInclude" > </ Head> Imported.xml <? xml version = "1.0"?> <footer> © Contoso Corp, 2003 </ footer> und Die endgültige XML, die ich erhalte, lautet: <? xml version = "1.0"?> <Head> <xi: include href = " import.xml " xmlns : xi = " w3.org/2003/XInclude " /> </ Head> mache ich etwas falsch?
Sumit
In Java muss die Unterstützung für XInclude explizit aktiviert sein. Vielleicht erfordert Ihre Bibliothek die gleiche Vorbereitung?
Tomasz Nurkiewicz
Ich habe .net verwendet, um das XMl zu analysieren. Ich konnte das XML von Mads Solution importieren. Vielen Dank für Ihre Zeit.
Sumit
1
libxml unterstützt dies, großartig.
RishiD
1
Für Java müssen folgende Zeilen hinzugefügt werden: DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance (); dbFactory.setXIncludeAware (true);
Rahul Sahu
1

Die Lösung von Mads Hansen ist gut, aber um die externe Datei in .NET 4 erfolgreich lesen zu können, hat es einige Zeit gedauert, die Hinweise in den Kommentaren zu Resolvern, ProhibitDTD usw. zu verwenden.

So wird's gemacht:

        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
quelle