当我将XML文档从磁盘加载到XDocument时,该XDocument具有一个仅包含原始XML文档在磁盘上的位置的就绪属性BaseUri。换句话说,
XDocument doc = XDocument.Load(@"c:\temp\doc.xml");
Console.Out.WriteLine(doc.BaseUri);
// Outputs "file:///c:/temp/doc.xml"
如果我从头开始创建一个新的XDocument,它没有BaseUri。例如:
XDocument doc = new XDocument(new XElement("test"));
Console.Out.WriteLine(doc.BaseUri);
// Outputs nothing
我可以将这个新的XDocument分配给BaseUri吗?我希望能够生成新文档,为它们分配名称,并轻松地将这些名称与它们一起传递。
答案 0 :(得分:3)
据我所知,你不能轻易这样做。如果您设置了适当的选项,则可以在使用任何XmlReader
加载时执行此操作。这意味着您可以编写一个扩展方法,将其保存到MemoryStream
,然后从XmlTextReader
派生的自定义类中加载一个新文档,该文档覆盖BaseUri
。那会非常难看:(
答案 1 :(得分:3)
丑陋但最快的方式:
var doc = XElement.Parse(someXml);
doc.GetType()
.GetMethod("SetBaseUri", BindingFlags.NonPublic | BindingFlags.Instance)
.Invoke(doc, new object[] { "some uri" });
答案 2 :(得分:2)
在阅读LoadOptions.SetBaseUri之后,很明显LINQ to XML使用Annotations来实现BaseUri
属性的设置。这是不幸的,因为注释是内部类型System.Xml.Linq.BaseUriAnnotation
,您无权访问。我的建议是设置你自己的注释,如果它不是BaseUri
,它将使用它的值或null
的值。
public class MyBaseUriAnnotation
{
public XObject XObject { get; private set; }
private string baseUri = String.Empty;
public string BaseUri
{
get
{
if (String.IsNullOrEmpty(this.baseUri))
return this.XObject.BaseUri;
return this.baseUri;
}
set { this.baseUri = value; }
}
public MyBaseUriAnnotation(XObject xobject)
: this(xobject, String.Empty)
{
}
public MyBaseUriAnnotation(XObject xobject, string baseUri)
{
if (xobject == null) throw new ArgumentNullException("xobject");
this.XObject = xobject;
this.baseUri = baseUri;
}
}
然后,您可以使用方法将注释添加到您自己解析的XDocument
:
public static XDocument XDocumentFromString(string baseUri, string xml)
{
var xdoc = XDocument.Parse(xml);
xdoc.AddAnnotation(new MyBaseUriAnnotation(xdoc, baseUri));
return xdoc;
}
然后,只要您想找到BaseUri
,就可以使用扩展方法检索正确的BaseUri
:
public static string FindBaseUri(this XObject xobject)
{
if (xobject == null) throw new ArgumentNullException(xobject);
var baseUri = xobject.Annotation<MyBaseUriAnnotation>();
return baseUri != null ? baseUri.BaseUri : xobject.BaseUri;
}
答案 3 :(得分:0)
public class CustomXmlDocument : XmlDocument
{
public string CustomBaseURL { get; set; }
public override string BaseURI
{
get { return this.CustomBaseURL; }
}
}
CustomXmlDocument objXML=new CustomXmlDocument();
objXML.CustomBaseURL="BaseURI";
objXML.loadXml(xml document);