0

我正在尝试为 Xml 文件编写查询。这是我的输入 XML 文件:

<logentry
   revision="10034">
<date>2009-10-07T03:45:38.000000Z</date>
<paths>
<path
   kind="file"
   action="M">/trunk/org.eclipse.mylyn.tasks/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaRepositoryConnectorTest.java</path>
<path
   kind="file"
   action="M">/trunk/org.eclipse.mylyn.tasks/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/core/BugzillaRepositoryConnectorStandaloneTest.java</path>
</paths>
</logentry>

我正在尝试过滤日期 2006-05-01 和 2007-09-01 之间的所有日志。我的输出应该是这样的:

10034 2009-10-07 BugzillaRepositoryConnectorTest.java,BugzillaRepositoryConnectorStandaloneTest.java

这意味着对于 date1 和 date2 之间的每个特定修订号,我希望获得来自 tag 的所有文件的列表。我使用正则表达式将文件名与路径分开。
这是我的代码:

using(System.IO.StreamWriter file1= new System.IO.StreamWriter( @"/home/datehistory"))
            {XDocument log= XDocument.Load(@"/home/output.xml");
                var selected= from logs in log.Descendants("logentry")  
                select new
            {revno=logs.Attribute("revision").Value,
             date=logs.Element("date").Value,
             list1= {from files in logs.Element("paths").Element("path").Value
                        let match=Regex.Match(files,@"/([A-Za-z0-9\-]+.java)<",RegexOptions.IgnoreCase);
                    where match.Success
                    select new
                        {filename=match.Groups[1].Value }; }
                ???? "please help "     where date between 2006-05-01 and 2007-09-01 
            };
            foreach (var d in selected)
                {
                        file1.Write(d.revno);
                        file1.Write("\t");
                        file1.Write(d.date);
                        file1.Write("\t");
                    foreach item in d.list1
                    {file1.write(item);
                        file1.write("\t"); }
                    file1.write("\n");

                }           
4

2 回答 2

0

您是否考虑过更简单的方法?例如这样的:

        var xml =
@"<logentry
   revision='10034'>
<date>2009-10-07T03:45:38.000000Z</date>
<paths>
<path
   kind='file'
   action='M'>/trunk/org.eclipse.mylyn.tasks/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/BugzillaRepositoryConnectorTest.java</path>
<path
   kind='file'
   action='M'>/trunk/org.eclipse.mylyn.tasks/org.eclipse.mylyn.bugzilla.tests/src/org/eclipse/mylyn/bugzilla/tests/core/BugzillaRepositoryConnectorStandaloneTest.java</path>
</paths>
</logentry>";

        XDocument log= XDocument.Parse(xml);
        foreach (var entry in log.Descendants("logentry")) {
            var date = DateTime.Parse(entry.Element("date").Value);
            Console.WriteLine(date);
            foreach (var path in entry.Descendants("path")) {
                var idx = path.Value.LastIndexOf('/');
                Console.Write(path.Value.Substring(idx + 1) + ", ");
                }
            Console.WriteLine();
            }  
        }

这会留下一个尾随的“,”,但这只是一个示例,而不是 writelines,您可以将信息添加到结构或容器中,然后像原始示例一样将其输出到文件中。

于 2013-11-05T23:20:12.050 回答
0

尝试这个:

using System;
using System.IO;
using System.Xml.Linq;
using System.Linq;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        var outputPath = "outputPath.log";
        var xDoc = XDocument.Load("input.xml");
        var sb = new StringBuilder();
        xDoc.Descendants("logentry").Cast<XElement>()
            .Where(e =>
            {
                var date = DateTime.Parse(e.Descendants("date")
                    .FirstOrDefault().Value);
                return date >= new DateTime(2006, 5, 1) &&
                    date <= new DateTime(2007, 9, 1);
            }).ToList().ForEach(e =>
            {
                var revision = e.Attribute("revision").Value;
                var date = DateTime.Parse(e.Descendants("date")
                    .FirstOrDefault().Value).ToString("yyyy-MM-dd");
                sb.Append(String.Format("{0}\t", revision));
                sb.Append(String.Format("{0}\t", date));
                e.Descendants("path")
                    .Where(p => Path.GetExtension(p.Value).ToLower() == ".java")
                    .ToList().ForEach(p =>
                        sb.Append(String.Format("{0},",
                            Path.GetFileName(p.Value))));
                if (sb[sb.Length - 1] == ',')
                    sb.Length = sb.Length - 1;
                sb.AppendLine();
            });
        File.WriteAllText(outputPath, sb.ToString());
    }
}
于 2013-11-05T23:46:35.143 回答