【问题标题】:Editing xml on live in C#. Deleting nodes that contain specific value在 C# 中实时编辑 xml。删除包含特定值的节点
【发布时间】:2016-07-08 08:10:37
【问题描述】:

我有一个这样的 xml 文档:

<?xml version="1.0" encoding="UTF-16"?>
<Recordset>
  <Table>Recordset</Table>
  <Rows>
    <Row>
      <Fields>
        ...
        <Field>
          <Alias>StatusName</Alias>
          <Value>Scheduled</Value>
        </Field>
        <Field>
          <Alias>U_Revision</Alias>
          <Value>code00</Value>
        </Field>
        <Field>
          <Alias>U_Quantity</Alias>
          <Value>10.000000</Value>
        </Field>
        <Field>
          <Alias>U_ActualQty</Alias>
          <Value>0.000000</Value>
        </Field>
        ...
      </Fields>
    </Row>
    ...
    <Row>
      <Fields>
        ...
        <Field>
          <Alias>StatusName</Alias>
          <Value>Scheduled</Value>
        </Field>
        <Field>
          <Alias>U_Revision</Alias>
          <Value>code00</Value>
        </Field>
        <Field>
          <Alias>U_Quantity</Alias>
          <Value>150.000000</Value>
        </Field>
        <Field>
          <Alias>U_ActualQty</Alias>
          <Value>0.000000</Value>
        </Field>
        ...
      </Fields>
    </Row>
  </Rows>
</Recordset>

我在别名为 StatusName 的字段中有不同的值。有一些 Scheduled、notScheduled、Realeased、Finished 等值。我想做的是删除每个包含具有别名 StatusName 和值的节点的节点,可以说 Scheduled 或 Finished。

我想或多或少地这样做,但是我做错了什么。有人可以让我走正确的路吗?

            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.LoadXml(xml);
            XmlNodeList nodes = xmlDocument.SelectNodes("//Rows[@StatusName='Finished']");
            for (int i = nodes.Count - 1; i >= 0; i--)
            {
                nodes[i].ParentNode.RemoveChild(nodes[i]);
            }
            var newXml = nodes.ToString();

如果包含别名 StatusName 和特定值让我说 Finished,我想删除整个节点。

我希望结果是新的字符串变量。

【问题讨论】:

    标签: c# xml


    【解决方案1】:

    我假设,您将删除与您的条件匹配的整个 &lt;Row&gt; 即,

    <Row>
      <Fields>
        ...
        <Field>
          <Alias>StatusName</Alias>
          <Value>Finished</Value>
        </Field>
      </Fields>
    </Row> 
    

    所需的 XPath:

    //Row[Fields[Field[Alias[text()='StatusName'] and Value[text() = 'Finished']]]] 
    

    C#

    string xPath = @"//Row[Fields[Field[Alias[text()='StatusName'] and Value[text() = 'Finished']]]]";
    var nodes = xmlDocument.SelectNodes(xPath);
    for (int i = nodes.Count - 1; i >= 0; i--)
    {
        nodes[i].ParentNode.RemoveChild(nodes[i]);
    }
    var newXml = xmlDocument.OuterXml;
    

    【讨论】:

    • 您正确理解了我的预期结果。感谢您的回答,我已经按照 Furtiro 的建议完成了解决方法。这是更长的路,但是我在更改一些代码后做了我所期望的。无论如何,感谢您纠正我的 xPath。 +
    【解决方案2】:

    我喜欢使用带有 xml 的 DataTable,我发现它非常简单。 我使用 DataTable 来处理您的节点。 所以,我拿了你的 xml 文件并为你写了一些可能对你有帮助的代码:

    //READ THE XML FILE
    XmlDocument xmlDoc = new XmlDocument();
    //My path
    xmlDoc.LoadXml(Properties.Resources.test);
    
    //Read the xml file into a dataSet
    DataSet ds = new DataSet();
    XmlNodeReader xnr = new XmlNodeReader(xmlDoc);
    ds.ReadXml(xnr);
    
    //Your data will be store in the 4's dataTable of the dataSet ( the <field> )
    for(int i=0;i<ds.Tables[4].Rows.Count;i++)
    {
        //Check the value as you wish
        //Here i want to suppress all the <Field> nodes with <Value> = "Scheduled"
        if ( ds.Tables[4].Rows[i]["Value"].ToString().Equals("Scheduled"))
        {
            //RemoteAt will remove all the node, so the node <Field> in your example data
            ds.Tables[4].Rows.RemoveAt(i);
            //If you want to only remove the node <Value>  (and not all the <Field> node ) just do ds.Tables[4].Rows["Value"]=null;
         }
    }
    //Write your new content in a new xml file
    
    //As you wanted here you just read the new xml file created as a string
    using (var stringWriter = new StringWriter())
    using (var xmlTextWriter = XmlWriter.Create(stringWriter))
    {
        ds.WriteXml(xmlTextWriter);
        xmlTextWriter.Flush();
        stringWriter.GetStringBuilder().ToString();
        //Here the result is in stringWriter,  and  there is 6 <Field> nodes, and not 8 like before the suppress
    }
    
    //If you want to create a new xml file with the new content just do 
    ds.WriteXml(yourPathOfXmlFile);
    //( like rewriting the previous xml file )
    

    【讨论】:

    • 感谢您的回答。它不符合我的预期结果,因为我希望删除整行,但是感谢您的代码启发了我,我已经匹配了我的情况。非常感谢 !顺便说一句,这些数据集很有趣。
    猜你喜欢
    • 1970-01-01
    • 2021-06-28
    • 2012-03-13
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 2012-09-04
    • 2015-04-25
    • 2017-10-15
    相关资源
    最近更新 更多