2011-09-19 20 views
1

我正在使用.NET C#XML和LINQ來更新/刪除/插入我的XML文件。如何將外部XML包含到XML文件中 - 這兩個文件應該如何看起來像

我有一個XML文件看起來像下面(image1),我想只包含第二個XML文件。

第一個XML文件是原始文件,我不想觸摸此文件。所以我更喜歡第二個參考。文件(外部文件),所以我可以添加/刪除XML行而不是Mainf XML文件。

但是如何將第二個XML(外部文件)包含或合併到FIRST? 我只需要在RED框中看到標籤(請參閱RED盒子)。

<RewriterRule> 
    <LookFor>  </LookFor> 
    <SendTo>   </SendTo> 
</RewriterRule> 

問:

1 - 我需要什麼,所以我在XMLFILE 2(外部文件)代碼包含在XML文件1的代碼寫?

2-我的XML文件2(外部文件)應該如何顯示?事實上,我需要,我認爲標籤,因爲我讀XML XDocument xdoc = XDocument.Load(this.Server.MapPath(path));,做一些更新/刪除.....

Original file

IMAG2 - 外部文件 enter image description here

回答

4

那麼添加元素從第二個文件是很容易:

XDocument doc1 = XDocument.Load(MapPath("file1.xml")); 
doc1.Root.Element("Rules").Add(XDocument.Load(MapPath("file2.xml")).Root.Element("Rules").Elements("RewriterRule")); 

// now save to third file with e.g. 
doc1.Save(MapPath("updated.xml")); 
// or overwrite first file e.g. 
doc1.Save(MapPath("file1.xml")); 

在另一方面,術語「合併」意味着你可能想要做像識別元素基於某些ID或鍵,然後不發更復雜意味着添加新的元素,但覆蓋一些數據。如果您在編寫代碼時需要幫助,您需要提供更多關於您想要的合併過程的詳細信息。

[編輯]下面是關於如何使用一個參考的基於DTD機制給外部實體以包括XML片斷文件到另一個文檔中的一個示例:file1.xml如下:

<!DOCTYPE example [ 
    <!ENTITY e1 SYSTEM "fragment.xml"> 
]> 
<example> 
    <data> 
    <item>1</item> 
    &e1; 
    </data> 
</example> 

fragment.xml之如下:

<?xml version="1.0" encoding="utf-8" ?> 
<item>2</item> 

然後,在主文件中使用LINQ閱讀XML時和.NET 4.0,你需要確保你使用的設置爲解析DTD如的XmlReader

 XDocument doc; 
     using (XmlReader xr = XmlReader.Create("file1.xml", new XmlReaderSettings() { DtdProcessing = System.Xml.DtdProcessing.Parse })) 
     { 
      doc = XDocument.Load(xr); 
     } 
+0

謝謝你,你貼有用的代碼。但我關心的是:file1。其他第三方應用程序也使用xml,我不想直接在此文件中執行刪除/添加操作(可能只是包含對外部文件的引用)。所以我想只做file2.xml中的更新/刪除/添加...這是可能的嗎? – ethem

+0

W3C有一個XML包含機制XInclude http://www.w3.org/TR/xinclude/,但是微軟的XML解析器不支持這一點。唯一支持的方法是基於DTD的對外部實體的引用。我將發佈一個關於如何將它與LINQ to XML一起使用的例子。 –

+0

感謝Martin ......這正是我需要的。 – ethem

1

使用XInclude W3C標籤有更好的方法。這是我的LINQ to XML extention方法:

/// <summary> 
/// Linq to XML XInclude extentions 
/// </summary> 
public static class XIncludeExtention 
{ 
    #region fields 

    /// <summary> 
    /// W3C XInclude standard 
    /// Be aware of the different 2001 and 2003 standard. 
    /// </summary> 
    public static readonly XNamespace IncludeNamespace = "http://www.w3.org/2003/XInclude"; 

    /// <summary> 
    /// Include element name 
    /// </summary> 
    public static readonly XName IncludeElementName = IncludeNamespace + "include"; 

    /// <summary> 
    /// Include location attribute 
    /// </summary> 
    public const string IncludeLocationAttributeName = "href"; 

    /// <summary> 
    /// Defines the maximum sub include count of 25 
    /// </summary> 
    public const int MaxSubIncludeCountDefault = 25; 

    #endregion 


    #region methods 


    /// <summary> 
    /// Replaces XInclude references with the target content. 
    /// W3C Standard: http://www.w3.org/2003/XInclude 
    /// </summary> 
    /// <param name="xDoc">The xml doc.</param> 
    /// <param name="maxSubIncludeCount">The max. allowed nested xml includes (default: 25).</param> 
    public static void ReplaceXIncludes(this XDocument xDoc, int maxSubIncludeCount = MaxSubIncludeCountDefault) 
    { 
     ReplaceXIncludes(xDoc.Root, maxSubIncludeCount); 
    } 

    /// <summary> 
    /// Replaces XInclude references with the target content. 
    /// W3C Standard: http://www.w3.org/2003/XInclude 
    /// </summary> 
    /// <param name="xmlElement">The XML element.</param> 
    /// <param name="maxSubIncludeCount">The max. allowed nested xml includes (default: 25).</param> 
    public static void ReplaceXIncludes(this XElement xmlElement, int maxSubIncludeCount = MaxSubIncludeCountDefault) 
    { 
     xmlElement.ReplaceXIncludes(1, maxSubIncludeCount); 
    } 

    private static void ReplaceXIncludes(this XElement xmlElement, int subIncludeCount, int maxSubIncludeCount) 
    { 
     var results = xmlElement.DescendantsAndSelf(IncludeElementName).ToArray<XElement>(); // must be materialized 

     foreach (var includeElement in results) 
     { 
      var path = includeElement.Attribute(IncludeLocationAttributeName).Value; 
      path = Path.GetFullPath(path); 

      var doc = XDocument.Load(path); 
      if (subIncludeCount <= maxSubIncludeCount) // protect mutal endless references 
      { 
       // replace nested includes 
       doc.Root.ReplaceXIncludes(++subIncludeCount, maxSubIncludeCount); 
      } 
      includeElement.ReplaceWith(doc.Root); 
     } 
    } 

    #endregion 
} 

的代碼是由下面的博客帖子的啓發: http://catarsa.com/Articles/Blog/Any/Any/Linq-To-Xml-XInclude?MP=pv

而且XInclude的相關信息: http://msdn.microsoft.com/en-us/library/aa302291.aspx

+0

雖然此鏈接可能回答此問題,但最好包括答案的基本部分,並提供參考鏈接。如果鏈接頁面更改,則僅鏈接答案可能會失效。 – arne

相關問題