代码之家  ›  专栏  ›  技术社区  ›  James Sulak

我可以为xdocument分配baseuri吗?

  •  5
  • James Sulak  · 技术社区  · 17 年前

    当我将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吗?我希望能够生成新的文档,为它们指定名称,并轻松地将这些名称与它们一起传递。

    4 回复  |  直到 9 年前
        1
  •  2
  •   user7116    17 年前

    读后 LoadOptions.SetBaseUri 显然,linq to xml使用注释来实现 BaseUri 财产。这是很不幸的,因为注释是内部类型的 System.Xml.Linq.BaseUriAnnotation ,您无权访问。我的建议可能是设置您自己的注释,它将使用它的值或 巴苏里 如果不是 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;
    }
    

    然后每当你想找到 贝瑟里 ,可以使用扩展方法来检索正确的 巴苏里 以下内容:

    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;
    }
    
        2
  •  3
  •   Jon Skeet    17 年前

    据我所知,你做不容易。当你装载任何 XmlReader ,如果设置了适当的选项。这意味着你 能够 编写一个扩展方法,将其保存到 MemoryStream 然后从派生自 XmlTextReader 哪个飞越了 BaseUri . 但那会很难看:(

        3
  •  3
  •   Pixel    10 年前

    丑陋但最快的方法:

    var doc = XElement.Parse(someXml);
    doc.GetType()
             .GetMethod("SetBaseUri", BindingFlags.NonPublic | BindingFlags.Instance)
             .Invoke(doc, new object[] { "some uri" });
    
        4
  •  0
  •   user3725809    9 年前
     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);