使用 linq 写入新文件

use linq to write new file

所以我正在尝试根据从我拥有的 XDocument 中获得的信息创建一个新文件

 XDocument doc = XDocument.Load(@"path.to.x.document");
        StreamWriter sw = new StreamWriter(WriteFile);
        var variabila = (from x in doc.Descendants("sentence").Elements("word")
                      select new
                      {
                          lemma = x.Attribute("lemma")?.Value,
                          postag = x.Attribute("postag")?.Value
                      }).ToSOMETHING; //Here i need to store it to something so later I can use that something like this

因为某些引理对于不同的 postag 可以具有相同的值,postag 也可以对于不同的引理具有相同的值,如下所示:

lemma="somf" postag="S321"
lemma="areq" postag="O213"
lemma="somf" postag="O213"
lemma="werid" postag="S321"

所以我需要这样写文件。基本上,如果它是一个句子的结尾,它会另起一行。

if(SOMETHING.lemma == "." || SOMETHING.lemma == "!")
{
    sw.WriteLine(SOMETHING.lemma);
}
else
{
    sw.Write(SOMETHING.lemma + " " + SOMETHING.postag);
}

我已经尝试使用 Lookup 和字典,但是如果我使用字典,我会遇到异常,因为字典不能两次存储相同的键,并且查找可以避免该异常,但我需要它们按它们出现的顺序排列,以便仅在新文件中根据引理和邮标造句。

如果我没理解错的话,举个例子,你会有以下 xml:

<root>
    <sentence>
       <word lemma="somf" postag="S321" />
       <word lemma="areq" postag="O213" />
       <word lemma="somf" postag="O213" />
       <word lemma="werid" postag="S321" />
       <word lemma="." postag="" />
    </sentence>
    <sentence>
       <word lemma="areq" postag="O213" />
       <word lemma="somf" postag="S321" />
       <word lemma="werid" postag="S321" />
       <word lemma="somf" postag="O213" />
       <word lemma="." postag="" />
    </sentence>
</root>

你希望你的文件写成:

somf S321 areq O213 somf O213 werid S321.
areq O213 somf S321 werid S321 somf O213.

请注意,我假设您将 .! 作为最后一个元素,但您可以根据需要使用它。

然后你可以迭代每个 sentence 和它的 words (see the fiddle):

using(StreamWriter stream = new StreamWriter("result.txt"))
{
    XDocument doc = XDocument.Load(@"path.to.x.document");
    var sentences = doc.Descendants("sentence");
    foreach (var sentence in sentences)
    {
        var line = string.Empty;
        var words = sentence.Elements("word");
        var lastWord = words.LastOrDefault();
        foreach (var word in words.Take(words.Count()-1))
        {
            line = string.join(
               " ",
               line,
               word.Attribute("lemma").Value,
               word.Attribute("postag").Value
            );
        }
        line = string.Join(string.Empty, line, lastWord.Attribute("lemma").Value);
        stream.WriteLine(line);
    }
}