如何从linq查询中添加项目到字典?

时间:2017-11-12 06:18:43

标签: c# linq dictionary

我正在尝试检查xml文件中是否存在属性为“ id ”的节点disp-formula,该属性包含的值为deqnX-Y,其中X }和Y是整数,如果匹配,则在字典中以下面的方式添加它们

Key                             Value
"rid="deqnX""               "rid="deqnX-Y""
"rid="deqnX+1""             "rid="deqnX-Y""
...  ...
"rid="deqnY""               "rid="deqnX-Y""

incrementing value of X by 1 till it reaches Y

我已经尝试了下面的代码,但是卡在中途,我无法弄清楚要做什么。

 Dictionary<string, string> dict = new Dictionary<string, string>();

            XDocument doc = XDocument.Load(@"D:\Practice\test.xml",LoadOptions.PreserveWhitespace);
            var x =from y in doc.Descendants("disp-formula")
                   where y.Attribute("id").Value.Contains(@"deqn(\d+)-(\d+)")
                   select y.Attribute("id");
            foreach (var item in x)
            {

                dict.Add(item);
            }

以下是一个示例xml文件

<?xml version="1.0" encoding="UTF-8"?>
<article article-type="research">
<front>
<journal-meta>
<issn pub-type="paper">0327-286X</issn>
<publisher>
<publisher-name>IEEE</publisher-name>
</publisher>
</journal-meta>
<article-meta>
<article-id pub-id-type="doi">10.1245/11.202136</article-id>
<title-group>
<article-title>Dragon Ball Super popularity in USA</article-title>
</title-group>
</article-meta>
</front>
<body>
<sec id="S1">
<label>1.</label>
<p>....
<disp-formula id="deqn1">
...
</disp-formula>
</p>
</sec>
<sec id="S2">
<label>2.</label>
<p>...
<disp-formula id="deqn2-6">
...
</disp-formula></p>
<p>...
<disp-formula id="deqn7">
...
</disp-formula>
</p>
<p><disp-formula id="deqn8-10">
...
</disp-formula></p>
</sec>
</body>
</article>

这应该是运行程序后的字典项

Key                             Value
"rid="deqn2""               "rid=""deqn2-6""
"rid="deqn3""               "rid=""deqn2-6""
"rid="deqn4""               "rid=""deqn2-6""
"rid="deqn5""               "rid=""deqn2-6""
"rid="deqn6""               "rid=""deqn2-6""
"rid="deqn8""               "rid=""deqn8-10""
"rid="deqn9""               "rid=""deqn8-10""
"rid="deqn10""              "rid=""deqn8-10""

4 个答案:

答案 0 :(得分:5)

此问题包括:

  1. 找到与正则表达式匹配的元素
  2. 从匹配的字符串中获取X和Y
  3. 将X增加到Y并将它们存储在词典
  4. var dict = new Dictionary<string, string>();
    var xdoc = XDocument.Load(@"D:\Practice\test.xml", LoadOptions.PreserveWhitespace);
    var regex = new Regex(@"deqn(\d+)-(\d+)");
    
    // Get matches by the regex
    var matches = from dispFormula in xdoc.Descendants("disp-formula")
                    select regex.Match(dispFormula.Attribute("id").Value);
    // We want only successes
    matches = matches.Where(match => match.Success);
    
    foreach (var match in matches)
    {
        // If input string is "deqn2-6", 
        //   match.Groups[0].Value = "deqn2-6", 
        //   match.Groups[1].Value = "2", 
        //   match.Groups[2].Value = "6", so
        int x = int.Parse(match.Groups[1].Value);
        int y = int.Parse(match.Groups[2].Value);
    
        // Now we have to increment x until y
        for (int i = 0; x + i <= y; i++)
        {
            dict.Add($"deqn{x + i}", $"deqn{x}-{y}");
        }
    }
    
    foreach (var entry in dict)
    {
        Console.WriteLine($"Key={entry.Key}, Value={entry.Value}");
    }
    

    此输出

    Key=deqn2, Value=deqn2-6
    Key=deqn3, Value=deqn2-6
    Key=deqn4, Value=deqn2-6
    Key=deqn5, Value=deqn2-6
    Key=deqn6, Value=deqn2-6
    Key=deqn8, Value=deqn8-10
    Key=deqn9, Value=deqn8-10
    Key=deqn10, Value=deqn8-10
    

答案 1 :(得分:2)

Dictionary<string, string> dict = new Dictionary<string, string>();

var regex = new Regex(@"deqn(\d+)-(\d+)");

XDocument doc = XDocument.Load(@"D:\Practice\test.xml", LoadOptions.PreserveWhitespace);
var x = from y in doc.Descendants("disp-formula")
        let m = regex.Match(y.Attribute("id").Value)
        where m.Success
        select m;


foreach (var item in x)
{
    var from = int.Parse(item.Groups[1].Value);
    var to = int.Parse(item.Groups[2].Value);
    for (int i = from; i <= to; i++)\\< should be <=
        dict.Add("deqn" + i, item.Value);
}

答案 2 :(得分:1)

我已经测试了您的代码,但它不适用于您提供的Xml

所以最好使用Regex来查找序列,如下面的代码所示:

 Dictionary<string, string> dict = new Dictionary<string, string>();
 XDocument doc = XDocument.Load(@"C:\Practice\test.xml", LoadOptions.PreserveWhitespace);
 Regex reg = new Regex(@"deqn(\d+)-(\d+)");
 var x = from y in doc.Descendants("disp-formula").ToList()
                where reg.IsMatch(y.Attribute("id").Value)
                select y.Attribute("id");

正如我在评论中告诉您的那样,您无法将item添加到dic,对于计数器,您还可以使用Regex获取第一个数字,然后将其增加为:

int counter = 0;
 foreach (var item in x)
 {
   var str = item.Value.Split('-')[0];
   if (counter == 0)
      counter = Convert.ToInt16(new Regex(@"\d+$").Match(str).Value) - 1;
   dict.Add("deqn" + (counter++).ToString(), item.Value);
 }

真正的工作代码是:

int counter = 0;
Dictionary<string, string> dict = new Dictionary<string, string>();
XDocument doc = XDocument.Load(@"C:\Practice\test.xml", LoadOptions.PreserveWhitespace);
Regex reg = new Regex(@"deqn(\d+)-(\d+)");
(from y in doc.Descendants("disp-formula").ToList()
         where reg.IsMatch(y.Attribute("id").Value)
         select y.Attribute("id")).ToList().ForEach(item=>
          {

            if (counter == 0)
                 counter = Convert.ToInt16(new Regex(@"\d+$").Match(item.Value.Split('-')[0]).Value) - 1;
                 dict.Add("deqn" + (++counter).ToString(), item.Value);
});

答案 3 :(得分:1)

这是我想要构建的最终程序

string[] path=Directory.GetDirectories(textBox1.Text,"xml",SearchOption.AllDirectories)
                .SelectMany(x=>Directory.GetFiles(x,"*.xml",SearchOption.AllDirectories)).ToArray();
            Dictionary<string, string> dict = new Dictionary<string, string>();
            var regex = new Regex(@"deqn(\d+)-(\d+)");
            foreach (var file in path) {
                dict.Clear();
                XDocument doc = XDocument.Load(file, LoadOptions.PreserveWhitespace);
                var x = from y in doc.Descendants("disp-formula")
                    let m = regex.Match(y.Attribute("id").Value)
                    where m.Success
                    select m;
                foreach (var item in x)
                {
                    var from = int.Parse(item.Groups[1].Value);
                    var to = int.Parse(item.Groups[2].Value);
                    for (int i = from; i <= to; i++)
                        dict.Add("rid=\"deqn" + i+"\"", "rid=\""+item.Value+"\"");

                    foreach (KeyValuePair<string,string> element in dict) {
                        string text=File.ReadAllText(file);
                        text=text.Replace(element.Key,element.Value);
                        File.WriteAllText(file, text);
                    }

                }
            }
            MessageBox.Show("Done");

感谢@lomed和@Mike Mat帮我解决这个问题......:)