Могу ли я назначить BaseUri XDocument? - PullRequest
5 голосов
/ 17 сентября 2009

Когда я загружаю 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 ]

3 голосов
/ 17 сентября 2009

Насколько я могу сказать, вы не можете легко сделать это. Вы можете сделать это при загрузке с любым XmlReader, если вы установите соответствующую опцию. Это означает, что вы могли бы написать метод расширения, который сохранил его в MemoryStream, а затем загрузить новый документ из пользовательского класса, производного от XmlTextReader, который переопределил BaseUri. Это было бы довольно уродливо, хотя: (

3 голосов
/ 02 июня 2016

Уродливый, но самый быстрый способ:

var doc = XElement.Parse(someXml);
doc.GetType()
         .GetMethod("SetBaseUri", BindingFlags.NonPublic | BindingFlags.Instance)
         .Invoke(doc, new object[] { "some uri" });
2 голосов
/ 17 сентября 2009

После прочтения LoadOptions.SetBaseUri становится очевидно, что LINQ to XML использует аннотации для достижения установки свойства 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;
}
0 голосов
/ 16 июня 2017
 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);
...