我正在使用.NET C#XML和LINQ来更新/删除/插入我的XML文件。
我有一个XML文件,如下图(image1),我想仅仅包含第二个XML文件。
第一个XML文件是原始文件,我不想触摸此文件。所以我更喜欢参考第二个。文件(外部文件)所以我可以在那里添加/删除XML行而不是Mainf XML文件。
但是如何将第二个XML(外部文件)包含或合并到FIRST中呢? 我只需要看到红色框中的标签(参见RED框)。
<RewriterRule>
<LookFor> </LookFor>
<SendTo> </SendTo>
</RewriterRule>
问题:
1-我需要为XML文件1中的代码编写什么,以便包含XMLfile 2(外部文件)中的代码?
2-我的XMLfile 2(外部文件)应该如何?事实上我需要我认为的标签,因为我正在阅读XML XDocument xdoc = XDocument.Load(this.Server.MapPath(path));
并做一些更新/删除......
IMAG2 - 外部文件
答案 0 :(得分: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或键识别元素,然后不是简单地添加新元素而是覆盖一些数据。如果您需要编写代码的帮助,则需要提供有关所需合并过程的详细信息。
[edit]下面是一个示例,介绍如何使用基于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 to XML和.NET 4.0读取主文件时,您需要确保您使用的XmlReader设置为解析DTD,例如。
XDocument doc;
using (XmlReader xr = XmlReader.Create("file1.xml", new XmlReaderSettings() { DtdProcessing = System.Xml.DtdProcessing.Parse }))
{
doc = XDocument.Load(xr);
}
答案 1 :(得分:1)
XInclude W3C标签有更好的方法。这是我的Linq to XML扩展方法:
/// <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