更改下一个兄弟的属性值

时间:2014-07-26 06:23:11

标签: c# xml xpath

我正在尝试从gridview中删除所选节点,并更改该属性的每个下一个兄弟的Id属性。它删除了节点,但问题是它没有改变属性(将id值减1)。我认为问题在于我的每个循环。

<Root>
  <Class Name="ECMInstruction" Style="Top">
    <Entity Id="1" Name="DocumentInformation" />
    <Property Id="1">
    </Property>
    <Property Id="2">
      <Lists>
        <ListName>ws_Users</ListName>
         <ListName>dfdfdfd</ListName>
      </Lists>
    </Property>
    <Property Id="3">
    </Property>
    <Property Id="4">
      <Lists>
        <ListName>ws_Users</ListName>
         <ListName>dfdfdfd</ListName>
      </Lists>
    </Property>
    <Property Id="5">
    </Property>
  </Class>
</Root>

和代码

XmlDocument xDoc = new XmlDocument();
xDoc.Load("sample.xml");
int value = 0;
foreach (DataGridViewRow row in dgv.SelectedRows)
{
    int rowval = row.Index;
    String propertyId = (dgv[0, rowval].Value.ToString());
    String propertyName = (dgv[1, rowval].Value.ToString());
    var nodeTobeRemoved = xDoc.SelectSingleNode("//Class[@Name='" + getCurClass() + "']");
    var confirmResult = MessageBox.Show("Are you sure to delete propert set \"" + propertyName + "\" ?", "Confirm Deletion!!", MessageBoxButtons.YesNo);
    if (confirmResult == DialogResult.Yes)
    {
        nodeTobeRemoved.RemoveChild(nodeTobeRemoved.SelectSingleNode("Property[@Name='" + propertyName + "']"));
        xDoc.Save("sample.xml");                       
        MessageBox.Show("Property set named \"" + propertyName + "\" from document class \"" + getCurClass() + "\" has been deleted !");
    }
    XmlNodeList ids = xDoc.SelectNodes("//Class[@Name='" + getCurClass() + "']/Property[@Id='" + propertyId + "']/following-sibling::Property");
    foreach (XmlNode i in ids)
    {
        int.TryParse(i.Attributes["Id"].Value, out value);
        value = value - 1;
        String newValue = value.ToString();
        i.Attributes["Id"].Value = newValue;
        xDoc.Save("sample.xml");
    }
    dgv.Rows.RemoveAt(rowval);
    dgv.ClearSelection();
    getProperties();
}

2 个答案:

答案 0 :(得分:1)

您尝试选择已删除的节点的以下兄弟节点。那不行。

试试这样。 (另外,如果你真的需要一个实际上什么都没有的ID属性 - 你可以通过在XPath中声明<Property>来选择第三个Property[3],{{1}没有任何实际目的,并导致像你刚刚遇到的问题。)

id="3"

替代

  • 您可以使用XmlDocument xDoc = new XmlDocument(); xDoc.Load("sample.xml"); foreach (DataGridViewRow row in dgv.SelectedRows) { var propertyId = dgv[0, row.Index].Value.ToString(); var propertyName = dgv[1, row.Index].Value.ToString(); var propertyNode = xDoc.SelectSingleNode("//Class[@Name='" + getCurClass() + "']/Property[@Name='" + propertyName + "']"); if (propertyNode != null) { var remainingProperties = propertyNode.SelectNodes("./following-sibling::Property"); var confirmMessage = "Are you sure to delete property set \"" + propertyName + "\" ?"; if (MessageBox.Show(confirmMessage, "Confirm Deletion!!", MessageBoxButtons.YesNo) == DialogResult.Yes) { foreach (XmlNode p in remainingProperties) { var idAttr = p.Attributes["Id"]; if (idAttr != null) { int value = 0; if (int.TryParse(idAttr.Value, out value)) {; idAttr.Value = (value - 1).ToString(); } } } propertyNode.ParentNode.RemoveChild(propertyNode); } xDoc.Save("sample.xml"); dgv.Rows.RemoveAt(rowval); dgv.ClearSelection(); getProperties(); } } 代替propertyNode.SelectNodes("./preceding-sibling::Property").Count + 1,而不是@id等。
  • 完全删除int.TryParse()属性并免除麻烦。

答案 1 :(得分:0)

我找到了问题的答案。我基本上从所选属性的属性兄弟中更改了所有Id变量,然后我留下了两个具有相同Id但具有不同名称的属性。最后,我删除了具有所选名称的属性。瞧!

        XmlDocument xDoc = new XmlDocument();
        xDoc.Load("sample.xml");
        foreach (DataGridViewRow row in dgv.SelectedRows)
        {
            int rowval = row.Index;
            String propertyID = (dgv[0, rowval].Value.ToString());
            String propertyName = (dgv[1, rowval].Value.ToString());
            var propertyNode = xDoc.SelectNodes("//Class[@Name='" + getCurClass() + "']/Property[@Id='" + propertyID + "']/following-sibling::Property");
            if (propertyNode != null)
            {
                var confirmMessage = "Are you sure to delete propert set \"" + propertyName + "\" ?";
                if (MessageBox.Show(confirmMessage, "Confirm Deletion!!", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    foreach (XmlNode p in propertyNode)
                    {
                        int value = 0;
                        int.TryParse(p.Attributes["Id"].Value, out value);
                        value = value - 1;
                        String newValue = value.ToString();
                        p.Attributes["Id"].Value = newValue;
                        xDoc.Save("sample.xml");

                    }
                }
            }

            var selectedRow = xDoc.SelectSingleNode("//Class[@Name='" + getCurClass() + "']/Property[@Name='" + propertyName + "']");
            selectedRow.ParentNode.RemoveChild(selectedRow);
            xDoc.Save("sample.xml");
        }