Podemos importar um arquivo XML para outro arquivo XML?

83

Podemos importar um arquivo XML para outro arquivo XML?

Quero dizer, existe alguma tag de importação em XML que leva o caminho XML como parâmetro e importa XML (para o qual o caminho é fornecido).

Sumit
fonte

Respostas:

93

Você pode usar uma entidade geral externa (analisada) .

Você declara a entidade assim:

<!ENTITY otherFile SYSTEM "otherFile.xml">

Então você o referencia assim:

&otherFile;

Um exemplo completo:

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

Quando o analisador XML lê o arquivo, ele expande a referência da entidade e inclui o arquivo XML referenciado como parte do conteúdo.

Se o "otherFile.xml" continha: <baz>this is my content</baz>

Então o XML seria avaliado e "visto" por um analisador XML como:

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

Algumas referências que podem ser úteis:

Mads Hansen
fonte
1
Oi Mads, estou preso nisso. O que acontece é que quando eu vejo meu arquivo main.xml no IE, estou obtendo o texto do meu otherFile.xml corretamente, mas quando eu uso o mesmo conceito em meu aplicativo e carrego meu xml no XMLDocument de .net então eu não estou recebendo o texto de otherFile.xml em vez disso estou recebendo tudo o que está escrito em main.xml que é tudo <? xml version = "1.0" standalone = "no"?> <! DOCTYPE doc [<! ENTITY otherFile SYSTEM "otherFile.xml">]> <doc> <foo> <bar> & otherFile; </bar> </foo> </doc> você pode me dizer se eu preciso fazer outra coisa para carregá-lo em meu xmldocument ???
Sumit,
3
Não estou muito familiarizado com a API .NET. No entanto, você pode precisar ver como a XMLResolverpropriedade está definida. Se a propriedade XMLResolver não estiver configurada em seu objeto XMLDocument, ele pode não carregar recursos externos. msdn.microsoft.com/en-us/library/5fcwybb2.aspx
Mads Hansen
1
navegadores como o Chrome entendem isso?
Alp,
3
navegadores podem desativar isso por razões de segurança para arquivos locais. use --allow-file-access-from-files switch para chrome ou faça upload para o host
premek.v
1
No .NET, defina o XmlResolver (criando um XmlUriResolver padrão) e ProhibitDTD (como false) no XmlReaderSettings para obter problemas de permissão anteriores. Por padrão, parece que a política de segurança do Windows / .NET não permite o carregamento de recursos externos.
João Jesus
26

As outras respostas cobrem as 2 abordagens mais comuns, entidades externas Xinclude e XML. A Microsoft tem um ótimo artigo sobre porque alguém deve preferir o Xinclude, bem como vários exemplos de implementações. Citei a comparação abaixo:

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

Por que XInclude?

A primeira pergunta que se pode fazer é "Por que usar XInclude em vez de entidades externas XML?" A resposta é que as entidades externas de XML têm uma série de limitações conhecidas e implicações inconvenientes, que efetivamente as impedem de serem um recurso de inclusão de propósito geral. Especificamente:

  • Uma entidade externa XML não pode ser um documento XML independente completo - nem a declaração XML autônoma nem a declaração Doctype são permitidas. Isso significa que uma entidade externa XML em si não pode incluir outras entidades externas.
  • Uma entidade externa XML deve ser um XML bem formado (não tão ruim à primeira vista, mas imagine que você deseja incluir código C # de amostra em seu documento XML).
  • Deixar de carregar uma entidade externa é um erro fatal; qualquer recuperação é estritamente proibida.
  • Apenas a entidade externa inteira pode ser incluída, não há como incluir apenas uma parte de um documento. - As entidades externas devem ser declaradas em um DTD ou em um subconjunto interno. Isso abre uma caixa de Pandora cheia de implicações, como o fato de que o elemento do documento deve ser nomeado na declaração Doctype e que os leitores de validação podem exigir que o modelo de conteúdo completo do documento seja definido no DTD, entre outros.

As deficiências de usar entidades externas XML como mecanismo de inclusão são conhecidas há algum tempo e de fato geraram o envio da Proposta de Inclusão de XML ao W3C em 1999 pela Microsoft e IBM. A proposta definiu um modelo de processamento e sintaxe para um recurso de inclusão XML de propósito geral.

Quatro anos depois, a versão 1.0 do XML Inclusions, também conhecido como Xinclude, é uma recomendação candidata, o que significa que o W3C acredita que foi amplamente revisado e satisfaz os problemas técnicos básicos que se propôs a resolver, mas ainda não é um recomendação completa.

Outro bom site que fornece uma variedade de exemplos de implementação é https://www.xml.com/pub/a/2002/07/31/xinclude.html . Abaixo está um exemplo de caso de uso comum de seu site:

<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
fonte
1
É uma comparação entre entidades externas Xinclude e XML, ambas as duas principais respostas e já mostram ou fornecem exemplos de uso. Achei que isso contribuía para a discussão e era muito longo / complicado para um comentário. Da mesma forma, a pergunta pergunta "pode" e não "como", de modo que, no que diz respeito a responder a uma pergunta generalizada, isso vai no sentido de esclarecer a direcionalidade que eu senti que era realmente a intenção da pergunta. Muitas outras boas referências sobre implementação específica. Dito isto, obrigado pelo feedback. Estou atualizando com um exemplo em breve.
VoteCoffee
Agradeço sua resposta e respeito por ter tentado resolver o problema adicionando um exemplo, mas acho que sua resposta ainda está fundamentalmente errada. Geralmente, ao citar texto de outro lugar, você deve incluir esse texto em uma aspas (para que seja óbvio que você não está tentando plagiar) e, mais importante, forneça sua própria discussão acima / abaixo da aspas que explique claramente por que você citou esse texto específico e como ele ajuda a responder à pergunta. Se fizer ambas as coisas e comentar novamente (para ser notificado), terei prazer em deletar meu comentário e retirar meu voto negativo.
Dan Bechard,
Atualizado com citações em bloco e comentários
VoteCoffee
Esta é uma resposta significativamente melhor! Votei e excluiu meu primeiro comentário que não é mais verdade. Vou deixar o outro comentário para contextualizar e, espero, ajudar futuros leitores a escreverem respostas melhores.
Dan Bechard,
11

Este recurso é denominado Inclusões XML (XInclude) . Alguns exemplos:

Tomasz Nurkiewicz
fonte
Eu tentei com msdn.microsoft.com/en-us/library/aa302291.aspx, mas sem uso :( Meus Xmls são main.xml <? Xml version = "1.0"?> <Head> <xi: include href = "importado.xml" xmlns: xi = " w3.org/2003/XInclude" > </Head> Imported.xml <? xml version = "1.0"?> <footer> © Contoso Corp, 2003 </footer> e o xml final que obtenho é. <? xml version = "1.0"?> <Head> <xi: include href = " import.xml " xmlns: xi = " w3.org/2003/XInclude " /> </Head> estou fazendo algo errado?
Sumit
Em Java, o suporte para XInclude deve ser ativado explicitamente. Talvez sua biblioteca exija a mesma preparação?
Tomasz Nurkiewicz
Eu estava usando .net para analisar o XMl, consegui importar o XML da Mads Solution .. obrigado pelo seu tempo ..
Sumit
1
libxml suporta isso, incrível.
RishiD
1
Para Java, as linhas abaixo precisam ser adicionadas- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance (); dbFactory.setXIncludeAware (true);
Rahul Sahu
1

A solução de Mads Hansen é boa, mas para ter sucesso na leitura do arquivo externo no .NET 4 levou algum tempo para descobrir usando dicas nos comentários sobre resolvers, ProhibitDTD e assim por diante.

Assim que se faz:

        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
fonte