在 C# 中实时编辑 xml.删除包含特定值的节点

本文关键字:包含特 节点 删除 xml 实时 编辑 | 更新日期: 2023-09-27 17:56:03

我有一个像这样的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>

我在别名为状态名称的字段中有不同的值。有一些"已计划"、"未计划"、"已实现"、"已完成"等值。我想做的是删除包含别名为状态名称和值的节点的每个节点,例如"已计划"或"已完成"。

我想或多或少地以这种方式做到这一点,但我做错了什么。有人可以让我走正确的路吗?

            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();

如果包含别名状态名称和特定值,我想删除整个节点

,比如说完成。

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

在 C# 中实时编辑 xml.删除包含特定值的节点

我喜欢

用xml使用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 )

我假设,您将删除符合您条件的整个<Row>即,

<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;