Chúng ta có thể nhập tệp XML vào một tệp XML khác không?


83

Chúng ta có thể nhập một tệp XML vào một tệp XML khác không?

Ý tôi là có bất kỳ thẻ nhập nào trong XML lấy đường dẫn XML làm tham số và nhập XML (cho đường dẫn nào được cung cấp).

Câu trả lời:


93

Bạn có thể sử dụng một thực thể chung bên ngoài (được phân tích cú pháp) .

Bạn khai báo thực thể như sau:

<!ENTITY otherFile SYSTEM "otherFile.xml">

Sau đó, bạn tham khảo nó như thế này:

&otherFile;

Một ví dụ hoàn chỉnh:

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

Khi trình phân tích cú pháp XML đọc tệp, nó sẽ mở rộng tham chiếu thực thể và bao gồm tệp XML được tham chiếu như một phần của nội dung.

Nếu "otherFile.xml" chứa: <baz>this is my content</baz>

Sau đó, XML sẽ được đánh giá và "nhìn thấy" bởi một trình phân tích cú pháp XML như:

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

Một số tài liệu tham khảo có thể hữu ích:


1
Xin chào Mads, tôi bị mắc kẹt ở điều này, điều gì đang xảy ra Khi tôi xem tệp main.xml của mình trong IE thì tôi nhận được văn bản của tệp otherFile.xml đúng cách nhưng khi tôi sử dụng cùng một khái niệm trong ứng dụng của mình và tải xml của tôi vào XMLDocument của .net thì tôi không nhận được văn bản của otherFile.xml thay vào đó, tôi nhận được bất cứ thứ gì được viết trong main.xml, tất cả đều là <? xml version = "1.0" standalone = "no"?> <! DOCTYPE doc [<! ENTITY otherFile SYSTEM "otherFile.xml">]> <doc> <foo> <bar> & otherFile; </bar> </foo> </doc> bạn có thể cho tôi biết nếu tôi cần làm gì khác để tải nó vào xmldocument ???
Sumit

3
Tôi không quen thuộc với api .NET. Tuy nhiên, bạn có thể cần xem thuộc XMLResolvertính được đặt thành gì. Nếu thuộc tính XMLResolver không được đặt trên đối tượng XMLDocument của bạn, thì nó có thể không tải các tài nguyên bên ngoài. msdn.microsoft.com/en-us/library/5fcwybb2.aspx
Mads Hansen

1
các trình duyệt như chrome có hiểu điều này không?
Alps,

3
trình duyệt có thể tắt tính năng này vì lý do bảo mật cho các tệp cục bộ. sử dụng --allow-file-access-from-files switch cho chrome hoặc tải lên máy chủ lưu trữ
premek.v

1
Trong .NET, đặt XmlResolver (bằng cách tạo XmlUriResolver mặc định) và Pro cấmDTD (thành false) trong XmlReaderSettings để giải quyết các vấn đề về quyền trước đây. Theo mặc định, có vẻ như chính sách bảo mật của Windows / .NET không cho phép tải các tài nguyên bên ngoài.
John Jesus

26

Các câu trả lời khác bao gồm 2 cách tiếp cận phổ biến nhất, Xinclude và các thực thể bên ngoài XML. Microsoft có một bài viết thực sự tuyệt vời về lý do tại sao người ta nên thích Xinclude, cũng như một số triển khai ví dụ. Tôi đã trích dẫn so sánh bên dưới:

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

Tại sao XInclude?

Câu hỏi đầu tiên mà người ta có thể hỏi là "Tại sao lại sử dụng XInclude thay vì các thực thể bên ngoài XML?" Câu trả lời là các thực thể bên ngoài XML có một số hạn chế nổi tiếng và các tác động bất tiện, điều này ngăn cản chúng một cách hiệu quả để trở thành cơ sở đưa vào mục đích chung. Đặc biệt:

  • Một thực thể bên ngoài XML không thể là một tài liệu XML độc lập hoàn chỉnh — không được phép khai báo XML độc lập hoặc khai báo Doctype. Điều đó có nghĩa là bản thân một thực thể bên ngoài XML không thể bao gồm các thực thể bên ngoài khác.
  • Một thực thể bên ngoài XML phải là XML được định dạng tốt (thoạt nhìn thì không tệ lắm, nhưng hãy tưởng tượng bạn muốn đưa mã C # mẫu vào tài liệu XML của mình).
  • Không thể tải một thực thể bên ngoài là một lỗi nghiêm trọng; bất kỳ sự phục hồi nào đều bị nghiêm cấm.
  • Chỉ có thể bao gồm toàn bộ thực thể bên ngoài, không có cách nào để chỉ bao gồm một phần của tài liệu. -Các thực thể bên ngoài phải được khai báo trong một DTD hoặc một tập hợp con bên trong. Điều này mở ra một Pandora's Box đầy ẩn ý, ​​chẳng hạn như thực tế là phần tử tài liệu phải được đặt tên trong khai báo Doctype và người đọc xác thực có thể yêu cầu mô hình nội dung đầy đủ của tài liệu được xác định trong DTD và những người khác.

Những khiếm khuyết của việc sử dụng các thực thể bên ngoài XML làm cơ chế bao gồm đã được biết đến trong một thời gian và trên thực tế đã dẫn đến việc Microsoft và IBM gửi Đề xuất bao gồm XML lên W3C vào năm 1999. Đề xuất đã xác định một mô hình xử lý và cú pháp cho một cơ sở bao gồm XML có mục đích chung.

Bốn năm sau, phiên bản 1.0 của XML Inclusions, còn được gọi là Xinclude, là Đề xuất Ứng viên, có nghĩa là W3C tin rằng nó đã được xem xét rộng rãi và đáp ứng các vấn đề kỹ thuật cơ bản mà nó đề ra để giải quyết, nhưng vẫn chưa khuyến nghị đầy đủ.

Một trang web tốt khác cung cấp nhiều cách triển khai mẫu là https://www.xml.com/pub/a/2002/07/31/xinclude.html . Dưới đây là một ví dụ về trường hợp sử dụng phổ biến từ trang web của họ:

<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
Đây là sự so sánh giữa Xinclude và các thực thể bên ngoài XML, cả hai đều là 2 câu trả lời hàng đầu và đã hiển thị hoặc cung cấp các ví dụ sử dụng. Tôi cảm thấy nó được thêm vào cuộc thảo luận và quá dài / phức tạp cho một bình luận. Tương tự như vậy, câu hỏi hỏi 'có thể' chứ không phải 'làm thế nào', vì vậy khi trả lời một câu hỏi tổng quát, điều này hướng tới việc làm rõ định hướng mà tôi cảm thấy thực sự là mục đích của câu hỏi. Rất nhiều tài liệu tham khảo hay khác về cách triển khai cụ thể. Đó là, nói rằng, cảm ơn bạn đã phản hồi. Tôi sẽ sớm cập nhật nó với một ví dụ.
VoteCoffee

Tôi đánh giá cao phản hồi của bạn và tôn trọng rằng bạn đã cố gắng giải quyết vấn đề bằng cách thêm một ví dụ, nhưng tôi nghĩ câu trả lời của bạn về cơ bản vẫn còn thiếu sót. Nói chung, khi trích dẫn văn bản từ nơi khác, bạn nên đưa văn bản đó vào một đoạn trích dẫn (để rõ ràng là bạn không cố đạo văn) và quan trọng hơn, cung cấp cuộc thảo luận của riêng bạn ở trên / bên dưới đoạn trích dẫn giải thích rất rõ ràng tại sao bạn đã trích dẫn văn bản cụ thể đó và cách nó giúp trả lời câu hỏi. Nếu thực hiện cả hai điều đó và nhận xét lại (vì vậy tôi nhận được thông báo), tôi sẽ sẵn lòng xóa nhận xét của mình và rút lại phiếu phản đối của mình.
Dan Bechard

Cập nhật với các trích dẫn và nhận xét khối
VoteCoffee

Đây là một câu trả lời tốt hơn đáng kể! Đã ủng hộ và xóa bình luận đầu tiên của tôi không còn đúng nữa. Tôi sẽ để lại nhận xét khác cho ngữ cảnh và hy vọng sẽ giúp các độc giả trong tương lai viết câu trả lời tốt hơn.
Dan Bechard

11

Tôi đã thử với msdn.microsoft.com/en-us/library/aa302291.aspx nhưng không sử dụng được :( Xmls của tôi là 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> và xml cuối cùng tôi nhận được là. <? xml version = "1.0"?> <Head> <xi: include href = " import.xml " xmlns: xi = " w3.org/2003/XInclude " /> </Head> tôi có đang làm gì sai không?
Sumit

Trong Java, hỗ trợ cho XInclude phải được bật rõ ràng. Có thể thư viện của bạn yêu cầu chuẩn bị tương tự?
Tomasz Nurkiewicz

Tôi đang sử dụng .net để phân tích cú pháp XMl, tôi đã có thể nhập XML bởi Mads Solution .. cảm ơn bạn đã dành thời gian ..
Sumit

1
libxml không hỗ trợ điều này, tuyệt vời.
RishiD

1
Đối với Java cần thêm các dòng bên dưới- DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance (); dbFactory.setXIncludeAware (true);
Rahul Sahu

1

Giải pháp của Mads Hansen là tốt nhưng để thành công trong việc đọc tệp bên ngoài trong .NET 4, phải mất một thời gian để tìm ra bằng cách sử dụng các gợi ý trong nhận xét về trình phân giải, Pro cấmDTD, v.v.

Đây là cách mà nó được hoàn thành:

        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>

event.txt:

<event>
    <item1>item1</item1>
    <item2>item2</item2>
</event>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.