【问题标题】:LINQ XML C# remove where condition in loopLINQ XML C# 删除循环中的 where 条件
【发布时间】:2019-07-18 06:59:04
【问题描述】:

尝试在特定条件下删除节点。基本上,如果选中某些复选框,我会向名为 upit 的 IENumerable 提供一个带有 WHERE 语句的额外查询。设置查询后,我试图删除它们,遍历每一个,但每次都没有被删除。

XDocument X = XDocument.Load(@"Financije.xml");
var upit = X.Element("POPIS").Elements("PODACI");

if (mjesec.Checked) { upit = upit.Where(E => (Convert.ToInt32(E.Element("MJESEC").Value) == Convert.ToInt32(mjesecbox.Text))); }
if (godina.Checked) { upit = upit.Where(E => (Convert.ToInt32(E.Element("GODINA").Value) == Convert.ToInt32(godinabox.Text))); }
if (ime.Checked) { upit = upit.Where(E => (E.Element("IME").Value.ToString().ToLower().Contains(search.Text.ToString().ToLower()))); }
if (opis.Checked) { upit = upit.Where(E => (E.Element("OPIS").Value.ToString().ToLower().Contains(search.Text.ToString().ToLower()))); }
if (veceod.Checked) { upit = upit.Where(E => (Convert.ToInt32(E.Element("CIJENA").Value.ToString()) > Convert.ToInt32(iznos.Text.ToString()))); }
if (manjeod.Checked) { upit = upit.Where(E => (Convert.ToInt32(E.Element("CIJENA").Value.ToString()) < Convert.ToInt32(iznos.Text.ToString()))); }

foreach (var item in upit)
{
    upit.Remove();
}

这是我的 XML 文件

<?xml version="1.0" encoding="utf-8"?>
<POPIS>
  <PODACI>
    <IME>test</IME>
    <CIJENA>200</CIJENA>
    <DATUM>12.1.2019</DATUM>
    <MJESEC>1</MJESEC>
    <GODINA>2019</GODINA>
    <OPIS>test123333</OPIS>
  </PODACI>
  <PODACI>
    <IME>voda</IME>
    <CIJENA>230</CIJENA>
    <DATUM>12.4.2018</DATUM>
    <MJESEC>4</MJESEC>
    <GODINA>2018</GODINA>
    <OPIS>yes123no</OPIS>
  </PODACI>
  <PODACI>
    <IME>oops</IME>
    <OPIS>nice</OPIS>
    <CIJENA>3</CIJENA>
    <MJESEC>5</MJESEC>
    <GODINA>2018<GODINA/>
    <DATUM>24.02.2019</DATUM>
  </PODACI>
  <PODACI>
    <IME>test</IME>
    <OPIS>123</OPIS>
    <CIJENA>1</CIJENA>
    <MJESEC>12</MJESEC>
    <GODINA>2019<GODINA/>
    <DATUM>24.02.2019</DATUM>
  </PODACI>
</POPIS>

【问题讨论】:

  • 一开始,如果你想保留原来的IEnumerable,你应该定义第二个,但似乎你只想要一个。接下来,如果你想删除一个项目,你应该使用upit.Remove(item);

标签: c# xml linq


【解决方案1】:

有点不清楚你想要结束什么,但我假设你想排除它们至少在选中复选框并且你正在进行的比较失败的情况下失败的项目。
所以下面在一个查询中实现它:

var X = XDocument.Load("Financije.xml");
var upit = X.Element("POPIS").Elements("PODACI");

var toRemove = upit.Where(u => 
    // If mjesec is not checked, skip the predicate, otherwise evaluate it.
    (!mjesec.Checked     || (Convert.ToInt32(u.Element("MJESEC").Value) == Convert.ToInt32(mjesecbox.Text)))
    // *And* do the same for godina and the rest of checkboxes...
    && (!godina.Checked  || (Convert.ToInt32(u.Element("GODINA").Value) == Convert.ToInt32(godinabox.Text)))
    && (!ime.Checked     || (u.Element("IME").Value.ToString().ToLower().Contains(search.Text.ToString().ToLower())))
    && (!opis.Checked    || (u.Element("OPIS").Value.ToString().ToLower().Contains(search.Text.ToString().ToLower())))
    && (!veceod.Checked  || (Convert.ToInt32(u.Element("CIJENA").Value.ToString()) > Convert.ToInt32(iznos.Text.ToString())))
    && (!manjeod.Checked || (Convert.ToInt32(u.Element("CIJENA").Value.ToString()) < Convert.ToInt32(iznos.Text.ToString()))));  

X.Element("POPIS").ReplaceAll(upit.Except(toRemove));
X.Save("Financije.xml");

【讨论】:

  • @Wuzbee 嗯,也许您可​​以尝试将 upit 的内容替换为 X.Element("POPIS").ReplaceWith(upit) 之类的内容?
  • 那么你确定l =&gt; l.Value == textBox1.ToString() 的结果是你想要的吗?没用是什么意思?
  • @Wuzbee 好的,我想我可以使用 .ReplaceAll().Save()。我认为它应该可以实现您想要的 - 请参阅编辑。
  • 嗯,那我们可以用.Except()吗?查看编辑。
  • 我正在浏览可用的功能并错过了那个。太感谢了!现在一切正常。
【解决方案2】:

试试看

XDocument X = XDocument.Load(@"Financije.xml");
    var upit = X.Element("POPIS").Elements("PODACI");
    //I‘m only on phone so please excuse, if I take the wrong Type. Assign to null, to prevent Compiler-Error 
    IEnumerable<XElement> upitPart= null;
    if (mjesec.Checked) { upitPart = upit.Where(E => (Convert.ToInt32(E.Element("MJESEC").Value) == Convert.ToInt32(mjesecbox.Text))); }
    if (godina.Checked) { upitPart = upitPart.Where(E => (Convert.ToInt32(E.Element("GODINA").Value) == Convert.ToInt32(godinabox.Text))); }
    if (ime.Checked) { upitPart = upitPart.Where(E => (E.Element("IME").Value.ToString().ToLower().Contains(search.Text.ToString().ToLower()))); }
    if (opis.Checked) { upitPart = upitPart.Where(E => (E.Element("OPIS").Value.ToString().ToLower().Contains(search.Text.ToString().ToLower()))); }
    if (veceod.Checked) { upitPart = upitPart.Where(E => (Convert.ToInt32(E.Element("CIJENA").Value.ToString()) > Convert.ToInt32(iznos.Text.ToString()))); }
    if (manjeod.Checked) { upitPart = upitPart.Where(E => (Convert.ToInt32(E.Element("CIJENA").Value.ToString()) < Convert.ToInt32(iznos.Text.ToString()))); }

if(upitPart != null)
{
    foreach (var item in upitPart)
    {
        upit.Remove(item);
    }
}

【讨论】:

  • 引发 2 个错误。 “无法在第 4 行创建抽象类或接口 'IEnumerable 的实例”和 upit.Remove(item) 处的“方法 'Remove' 没有重载需要 1 个参数”;
  • 做了一些改变试试看。
  • 还是同样的问题,看看。 link
  • 呃,你为什么基本上偷了@Nikolaus的答案?
猜你喜欢
  • 2021-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 2015-08-19
  • 1970-01-01
  • 1970-01-01
  • 2010-09-17
相关资源
最近更新 更多