在Linq查询后从Xdocument获取文件名

时间:2013-02-21 13:15:21

标签: c# xml linq linq-to-xml

我正在查询一堆特定元素和属性的SGML文档。这可以正常工作,并在找到包含指定项目的文件时显示一个消息框。但是,我需要它做的也是给我发现它们的文件的名称,否则它就是无用的。我似乎无法找到获取文件文件名的方法。我有:

XDocument doc = XDocument.Load(sgmlReader);
IEnumerable<XElement> selectedElement =
    from el in doc.Descendants(Element_textBox.Text)
        where (string)el.Attribute(Attribute_textBox.Text) == Value_textBox.Text
        select el; 
        //need to select the DMC and title and put in a variable, and list them


foreach (XElement elem in selectedElement)
   //Console.WriteLine(elem);

   MessageBox.Show("Data Module Found: " + elem);

正如我所说,我需要以某种方式识别查询找到匹配项的文件。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您可以指定必须在加载时设置文档的基URI:

var doc = XDocument.Load(@"file.xml", LoadOptions.SetBaseUri);

然后,您可以从任何元素获取文档URI:

var someElement = doc.Root;
var uri = element.Document.BaseUri;
Console.WriteLine(uri);    // Prints: file:///C:/file.xml

如果您使用的是StreamTextReader,则必须从其他地方获取文件名并自行存储。否则无法获取文件名。

想象一下,我将MemoryStreamNetworkStream传递给XDocument.Load(),然后没有文件名。通常,在使用流或阅读器时,您没有文件名。

但是有一个例外:如果您可以获取阅读器的基本流并将其转换为FileStream,那么您可以获取文件名:

var fs = File.OpenRead(@"C:\myxml.xml");
var reader = new StreamReader(fs);
DoSomething(reader);

static void DoSomething(TextReader reader)
{
    var streamReader = reader as StreamReader;
    if (streamReader != null)
    {
        var fileStream = streamReader.BaseStream as FileStream;
        if (fileStream != null)
            Console.WriteLine(fileStream.Name);
        else { /* No filename */ }
    }
    else { /* No filename */ }

    // ...
}