我可以将 BaseUri 分配给 XDocument 吗?

发布于 2024-08-05 21:56:35 字数 497 浏览 3 评论 0原文

当我将 XML 文档从磁盘加载到 XDocument 中时,该 XDocument 有一个只读属性 BaseUri,其中包含原始 XML 文档在磁盘上的位置。换句话说,

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 吗?我希望能够生成新文档,为它们分配名称,并轻松地传递这些名称。

When I load an XML document from disk into an XDocument, that XDocument has a ready-only property BaseUri that contains the original XML document's location on disk. In other words,

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

If I create a new XDocument from scratch, it has no BaseUri. For example:

XDocument doc = new XDocument(new XElement("test"));
Console.Out.WriteLine(doc.BaseUri);
// Outputs nothing

Can I assign this new XDocument a BaseUri? I'd like to be able to generate new documents, assign them names, and easily pass those names along with them.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

酒绊 2024-08-12 21:56:35

据我所知,你不能轻易做到这一点。如果您设置了适当的选项,则可以在使用任何 XmlReader 加载时执行此操作。这意味着您可以编写一个扩展方法,将其保存到MemoryStream,然后从派生自XmlTextReader的自定义类加载新文档,该类覆盖<代码>BaseUri。但这会很丑陋:(

As far as I can tell, you can't easily do so. You can do it when you load with any XmlReader, if you set the appropriate option. This means you could write an extension method which saved it to a MemoryStream then loaded a new document from a custom class derived from XmlTextReader which overrode BaseUri. That would be pretty ugly though :(

葬花如无物 2024-08-12 21:56:35

丑陋但最快的方法:

var doc = XElement.Parse(someXml);
doc.GetType()
         .GetMethod("SetBaseUri", BindingFlags.NonPublic | BindingFlags.Instance)
         .Invoke(doc, new object[] { "some uri" });

The ugly but the fastest way:

var doc = XElement.Parse(someXml);
doc.GetType()
         .GetMethod("SetBaseUri", BindingFlags.NonPublic | BindingFlags.Instance)
         .Invoke(doc, new object[] { "some uri" });
风月客 2024-08-12 21:56:35

阅读 LoadOptions.SetBaseUri 后很明显LINQ to XML 使用注释来实现 BaseUri 属性的设置。不幸的是,该注释属于内部类型 System.Xml.Linq.BaseUriAnnotation,您无权访问该类型。我的建议是设置您自己的注释,如果它不为 null,则使用它的值或 BaseUri 的值。

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;
}

After reading LoadOptions.SetBaseUri it is apparent that LINQ to XML uses Annotations to achieve the setting of the BaseUri property. This is unfortunate as the annotation is of the internal type System.Xml.Linq.BaseUriAnnotation, which you do not have access to. My suggestion would be to perhaps set your own annotation which would use either its value or the value of BaseUri if it was not 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;
    }
}

You can then use a method to add the annotation to an XDocument you parse on your own:

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

And then whenever you'd like to find the BaseUri, you could use an extension method to retrieve the correct 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;
}
摇划花蜜的午后 2024-08-12 21:56:35
 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);
 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文