我可以将BaseUri分配给XDocument吗?

Jam*_*lak 5 c# xml linq-to-xml

当我将XML文档从磁盘加载到XDocument时,该XDocument具有一个仅包含原始XML文档在磁盘上的位置的就绪属性BaseUri.换一种说法,

XDocument doc = XDocument.Load(@"c:\temp\doc.xml");
Console.Out.WriteLine(doc.BaseUri);
// Outputs "file:///c:/temp/doc.xml"
Run Code Online (Sandbox Code Playgroud)

如果我从头开始创建一个新的XDocument,它没有BaseUri.例如:

XDocument doc = new XDocument(new XElement("test"));
Console.Out.WriteLine(doc.BaseUri);
// Outputs nothing
Run Code Online (Sandbox Code Playgroud)

我可以将这个新的XDocument分配给BaseUri吗?我希望能够生成新文档,为它们分配名称,并轻松地将这些名称与它们一起传递.

use*_*116 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用一种方法将注释添加到XDocument您自己解析的内容中:

public static XDocument XDocumentFromString(string baseUri, string xml)
{
    var xdoc = XDocument.Parse(xml);
    xdoc.AddAnnotation(new MyBaseUriAnnotation(xdoc, baseUri));
    return xdoc;
}
Run Code Online (Sandbox Code Playgroud)

然后,每当您想查找 时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;
}
Run Code Online (Sandbox Code Playgroud)