¿Podemos importar un archivo XML a otro archivo XML?

83

¿Podemos importar un archivo XML a otro archivo XML?

Quiero decir, ¿hay alguna etiqueta de importación en XML que tome la ruta XML como parámetro e importe XML (para la que se proporciona la ruta)?

Sumit
fuente

Respuestas:

93

Puede utilizar una entidad general externa (analizada) .

Declaras la entidad así:

<!ENTITY otherFile SYSTEM "otherFile.xml">

Luego lo referencia de esta manera:

&otherFile;

Un ejemplo completo:

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

Cuando el analizador XML lee el archivo, expandirá la referencia de la entidad e incluirá el archivo XML referenciado como parte del contenido.

Si el "otherFile.xml" contenía: <baz>this is my content</baz>

Entonces el XML sería evaluado y "visto" por un analizador XML como:

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

Algunas referencias que pueden resultar útiles:

Mads Hansen
fuente
1
Hola Mads, estoy atascado en esto, lo que sucede es que cuando veo mi archivo main.xml en IE, obtengo el texto de mi otherFile.xml correctamente, pero cuando uso el mismo concepto en mi aplicación y cargo mi xml en XMLDocument de .net, entonces no obtengo el texto de otherFile.xml en su lugar, estoy recibiendo todo lo que está escrito en main.xml que es todo <? xml version = "1.0" standalone = "no"?> <! DOCTYPE doc [<! ENTITY otherFile SYSTEM "otherFile.xml">]> <doc> <foo> <bar> & otherFile; </bar> </foo> </doc> ¿puede decirme si necesito hacer algo más para cargarlo en mi xmldocument ???
Sumit
3
No estoy muy familiarizado con la API de .NET. Sin embargo, es posible que deba ver en qué XMLResolverestá configurada la propiedad. Si la propiedad XMLResolver no está establecida en su objeto XMLDocument, es posible que no cargue recursos externos. msdn.microsoft.com/en-us/library/5fcwybb2.aspx
Mads Hansen
1
¿Los navegadores como Chrome entienden esto?
Alp
3
Los navegadores pueden desactivar esto por razones de seguridad para archivos locales. use el interruptor --allow-file-access-from-files para Chrome o cárguelo en el host
premek.v
1
En .NET, configure XmlResolver (creando un XmlUriResolver predeterminado) y ProhibitDTD (en falso) en XmlReaderSettings para superar los problemas de permisos. De forma predeterminada, parece que la política de seguridad de Windows / .NET no permite la carga de recursos externos.
Juan Jesús
26

Las otras respuestas cubren los 2 enfoques más comunes, Xinclude y entidades externas XML. Microsoft tiene un artículo realmente bueno sobre por qué uno debería preferir Xinclude, así como varias implementaciones de ejemplo. He citado la siguiente comparación:

Según http://msdn.microsoft.com/en-us/library/aa302291.aspx

¿Por qué XInclude?

La primera pregunta que uno puede hacer es "¿Por qué utilizar XInclude en lugar de entidades externas XML?" La respuesta es que las entidades externas XML tienen una serie de limitaciones conocidas e implicaciones inconvenientes que impiden que sean una instalación de inclusión de propósito general. Específicamente:

  • Una entidad externa XML no puede ser un documento XML independiente en toda regla; no se permiten declaraciones XML independientes ni declaraciones Doctype. Eso significa efectivamente que una entidad externa XML en sí misma no puede incluir otras entidades externas.
  • Una entidad externa XML debe estar bien formada (no tan mal a primera vista, pero imagina que quieres incluir código C # de muestra en tu documento XML).
  • No cargar una entidad externa es un error fatal; cualquier recuperación está estrictamente prohibida.
  • Solo se puede incluir toda la entidad externa, no hay forma de incluir solo una parte de un documento. -Las entidades externas deben declararse en un DTD o un subconjunto interno. Esto abre una caja de Pandora llena de implicaciones, como el hecho de que el elemento del documento debe ser nombrado en la declaración Doctype y que los lectores de validación pueden requerir que el modelo de contenido completo del documento esté definido en DTD, entre otros.

Las deficiencias del uso de entidades externas XML como mecanismo de inclusión se conocen desde hace algún tiempo y, de hecho, dieron lugar a la presentación de la propuesta de inclusión XML al W3C en 1999 por Microsoft e IBM. La propuesta definió un modelo de procesamiento y una sintaxis para una instalación de inclusión XML de propósito general.

Cuatro años después, la versión 1.0 de XML Inclusions, también conocida como Xinclude, es una recomendación candidata, lo que significa que el W3C cree que ha sido ampliamente revisada y satisface los problemas técnicos básicos que se propuso resolver, pero aún no es una recomendación. recomendación completa.

Otro buen sitio que proporciona una variedad de implementaciones de ejemplo es https://www.xml.com/pub/a/2002/07/31/xinclude.html . A continuación se muestra un ejemplo de caso de uso común de su sitio:

<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
fuente
1
Es una comparación entre Xinclude y las entidades externas XML, las cuales son las 2 respuestas principales y ya muestran o proporcionan ejemplos de uso. Sentí que se agregó a la discusión y era demasiado largo / complicado para un comentario. De la misma manera, la pregunta pregunta "puedo" y no "cómo", por lo que en la medida en que se responde a una pregunta generalizada, se trata de aclarar la direccionalidad que sentí que era realmente la intención de la pregunta. Muchas otras buenas referencias sobre implementación específica. Dicho esto, gracias por los comentarios. Lo actualizaré con un ejemplo en breve.
VoteCoffee
Aprecio su respuesta y respeto por haber tratado de resolver el problema agregando un ejemplo, pero creo que su respuesta sigue siendo fundamentalmente defectuosa. Por lo general, al citar texto de otra parte, debe incluir ese texto en una cita en bloque (para que sea obvio que no está tratando de plagiar) y, lo que es más importante, proporcionar su propia discusión arriba / debajo de la cita en bloque que explique muy claramente por qué citó. ese texto en particular y cómo ayuda a responder la pregunta. Si hago ambas cosas y comenta de nuevo (para que me notifiquen), con mucho gusto eliminaré mi comentario y retiraré mi voto negativo.
Dan Bechard
Actualizado con citas y comentarios en bloque
VoteCoffee
¡Esta es una respuesta significativamente mejor! Voté y eliminé mi primer comentario, que ya no es cierto. Dejaré el otro comentario por contexto y, con suerte, para ayudar a los futuros lectores a escribir mejores respuestas.
Dan Bechard
11

Esta característica se llama Inclusiones XML (XInclude) . Algunos ejemplos:

Tomasz Nurkiewicz
fuente
Probé con msdn.microsoft.com/en-us/library/aa302291.aspx pero sin uso :( Mis Xmls son 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> y el xml final que obtengo es. <? xml version = "1.0"?> <Head> <xi: include href = " Published.xml " xmlns: xi = " w3.org/2003/XInclude " /> </Head> ¿Estoy haciendo algo mal?
Sumit
En Java, el soporte para XInclude debe habilitarse explícitamente. ¿Quizás tu biblioteca requiera la misma preparación?
Tomasz Nurkiewicz
Estaba usando .net para analizar el XMl, pude importar el XML por Mads Solution .. gracias por su tiempo ..
Sumit
1
libxml admite esto, increíble.
RishiD
1
Para Java, es necesario agregar las siguientes líneas: DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance (); dbFactory.setXIncludeAware (verdadero);
Rahul Sahu
1

La solución de Mads Hansen es buena, pero para tener éxito en la lectura del archivo externo en .NET 4 tomó algo de tiempo averiguar el uso de sugerencias en los comentarios sobre resolutores, ProhibitDTD, etc.

Así es como se hace:

        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>
usuario3717478
fuente