我们可以将XML文件导入另一个XML文件吗?


83

我们可以将一个XML文件导入另一个XML文件吗?

我的意思是说,XML中是否有任何导入标记,它将XML路径作为参数并导入XML(为其提供了路径)。

Answers:


93

您可以使用外部(已解析)的一般实体

您可以这样声明实体:

<!ENTITY otherFile SYSTEM "otherFile.xml">

然后,您可以像这样引用它:

&otherFile;

一个完整的例子:

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

XML解析器读取文件时,它将扩展实体引用,并将所引用的XML文件作为内容的一部分包括在内。

如果“ otherFile.xml”包含: <baz>this is my content</baz>

然后,XML解析器将对XML进行评估并“看到”为:

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

一些参考可能会有所帮助:


1
嗨,Mads,我被困在这里,发生的是当我在IE中查看main.xml文件时,然后正确获取了otherFile.xml的文本,但是当我在应用程序中使用相同的概念并将xml加载到XMLDocument中时.net,那么我没有得到otherFile.xml的文本,而是得到了main.xml中写的所有内容,全部都是<?xml version =“ 1.0” standalone =“ no”?> <!DOCTYPE doc [<! ENTITY otherFile SYSTEM“ otherFile.xml”>]> <doc> <foo> <bar>&otherFile; </ bar> </ foo> </ doc>是否可以告诉我是否需要做一些其他事情以将其加载到我的计算机中xmldocument ???
Sumit

3
我对.NET API不太熟悉。但是,您可能需要查看该XMLResolver属性设置为什么。如果未在XMLDocument对象上设置XMLResolver属性,则它可能不会加载外部资源。msdn.microsoft.com/en-us/library/5fcwybb2.aspx
Mads Hansen

1
chrome之类的浏览器能理解吗?
阿尔卑斯山

3
浏览器可能出于本地文件安全原因而禁用此功能。使用--allow-file-access-from-files开关切换至chrome或上传至主机
premek.v 2014年

1
在.NET中,在XmlReaderSettings中设置XmlResolver(通过创建默认的XmlUriResolver)和ProhibitDTD(为false)以解决过去的权限问题。默认情况下,似乎Windows / .NET安全策略不允许加载外部资源。
约翰·耶稣

26

其他答案涵盖两种最常见的方法,即Xinclude和XML外部实体。对于为什么要使用Xinclude以及一些示例实现,Microsoft撰写了非常好的文章。我引用了下面的比较:

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

为什么使用XInclude?

一个人可能会问的第一个问题是:“为什么使用XInclude而不是XML外部实体?” 答案是XML外部实体具有许多众所周知的局限性和不便的含义,这有效地阻止了它们成为通用包含工具。特别:

  • XML外部实体不能是成熟的独立XML文档-不允许独立XML声明或Doctype声明。这实际上意味着XML外部实体本身不能包含其他外部实体。
  • XML外部实体必须是格式良好的XML(乍看之下还不错,但是假设您想将示例C#代码包含在XML文档中)。
  • 无法加载外部实体是致命错误;严禁任何恢复。
  • 可能只包括整个外部实体,而没有办法只包含文档的一部分。-外部实体必须在DTD或内部子集中声明。这就打开了一个充满含义的潘多拉魔盒,例如必须在Doctype声明中命名文档元素,并且验证读者可能需要在DTD中定义文档的完整内容模型。

使用XML外部实体作为包含机制的缺陷已经有一段时间了,并且实际上催生了Microsoft和IBM在1999年向W3C提交XML包含提案的过程。该提案定义了通用XML包含工具的处理模型和语法。

四年后,XML Inclusions的1.0版(也称为Xinclude)成为候选推荐书,这意味着W3C认为它已经得到了广泛的审查,并且满足了其准备解决的基本技术问题,但尚未解决。全面推荐。

提供各种示例实现的另一个不错的站点是https://www.xml.com/pub/a/2002/07/31/xinclude.html。以下是他们网站上的一个常见用例示例:

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

1
它是Xinclude和XML外部实体之间的比较,两者都是最重要的两个答案,并且已经显示或提供了使用示例。我觉得它增加了讨论的内容,而且太长/太复杂,无法发表评论。同样,这个问题问的是“可以”而不是“如何”,因此,就回答一个广义的问题而言,这有助于澄清方向性,我认为这确实是问题的意图。关于特定实现的许多其他良好参考。话虽如此,谢谢您的反馈。我将用一个示例对此进行更新。
VoteCoffee

感谢您的回应和尊重,您尝试通过添加示例来解决此问题,但我认为您的回答仍然存在根本缺陷。通常,在引用其他地方的文本时,应将其包含在blockquote中(这样很明显,您不会not窃),更重要的是,请在blockquote的上方/下方提供自己的讨论,以清楚地说明为什么引用该特定文本及其如何帮助回答问题。如果同时执行这两项操作并再次发表评论(以便得到通知),我将很乐意删除我的评论并撤回我的拒绝投票。
丹·贝查德

用大块引用和注释更新
VoteCoffee '17

这是一个明显更好的答案!赞成并删除了我的第一条评论,该评论不再正确。我将其他评论留给上下文,以期帮助将来的读者写出更好的答案。
丹·贝查德

11

我确实尝试了 msdn.microsoft.com/zh-cn/library/aa302291.aspx, 但没有使用:(我的Xml是main.xml <?xml version =“ 1.0”?> <Head> <xi:include href =“ imported.xml” xmlns:xi =“ w3.org/2003/XInclude” > </ Head> Imported.xml <?xml version =“ 1.0”?> <footer>©Contoso Corp,2003 </ footer>和我得到的最终xml是<?xml version =“ 1.0”?> <Head> <xi:include href =“ imported.xml” xmlns:xi =“ w3.org/2003/XInclude ” /> </ Head>我做错什么了吗?
Sumit

在Java中,必须明确启用对XInclude的支持。也许您的图书馆需要进行同样的准备?
Tomasz Nurkiewicz 2011年

我使用.net解析XMl,我能够通过Mads Solution导入XML ..谢谢您的时间。.–
Sumit

1
libxml确实支持此功能。
RishiD

1
对于Java,需要添加以下几行-DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); dbFactory.setXIncludeAware(true);
拉胡尔·萨胡

1

Mads Hansen的解决方案很好,但是要成功读取.NET 4中的外部文件,需要花费一些时间来找出有关解析程序,ProhibitDTD等的注释中的提示。

这是这样做的:

        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>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.