C#,尝试将子节点添加到具有特定属性的节点

时间:2016-05-11 16:33:27

标签: c# xml wpf xpath

我正在尝试从WPF创建一个工具,通过将数据输入到文本框中,然后单击按钮将该数据输入到XML文档中,创建一个简单的XML文档。除了根元素之外,我将有一个带子子步元素的步骤元素,例如:

<root>
<step id="1">
    <P>some instructions</p>
    <step id="1.1">
        <p>some additional instructions</p>
    </step>
</step>
<step id="2">
    <p>second set of instructions</p>
    <step id="2.1">
        <p>additional instructions for step 2</p>
    </step>
</step>

我已经能够添加父步骤,但是我的所有子步骤都属于第一个父步骤:

<root>
<step id="1">
  <step id="1.1">
  <step id="2.1">
  <step id="3.1">
<step id="2">
<step id="3">

我正在尝试使用XPath将我的子步骤插入正确的父步骤。但是我收到错误: “XAttribute不包含'add'的定义,也没有扩展方法'add'接受第一个参数类型'XAttribute'。”

我已经进行了广泛的搜索,无法提出解决方案,希望这是有道理的,有人可以帮助我。先感谢您。这是我的代码:

using System.Windows;
using System.Xml.Linq;
using System.Xml.XPath;

namespace XMLwpfTest1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        XDocument doc = new XDocument(
           new XElement("Content",
           new XElement("Title", "DM Title"))
          );

        string par = "par-";

        int counter = 1;
        int counter2 = 1;
        string stepNumber = "";



        public MainWindow()
        {
            InitializeComponent();
        }

        private void create_Click(object sender, RoutedEventArgs e)
        {
            doc.Element("Content").Add(
                new XElement("proceduralStep",
                new XAttribute("id", par + counter.ToString("D4")),
                new XElement("para",
            dataBox.Text)));
            stepNumber = par + counter.ToString("D4");
            counter += 1;
            dataBox.Clear();
            counter2 = 1;
        }


        private void createSubStep_Click(object sender, RoutedEventArgs e)
        {

            var addStep = doc.XPathSelectElement("Content/proceduralStep").Attribute(stepNumber);


            addStep.add(
            new XElement("proceduralStep",
            new XAttribute("id", stepNumber + "-" + counter2.ToString("D4")),
            new XElement("para",
        subDataBox.Text)));
            counter2 += 1;
            subDataBox.Clear();
        }

        private void save_Click(object sender, RoutedEventArgs e)
        {
            doc.Save(fileName.Text + ".xml");
            savedLabel.Visibility = Visibility.Visible;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

你的问题出现在这一行:

var addStep = doc.XPathSelectElement("Content/proceduralStep").Attribute(stepNumber);

您似乎想要选择<proceduralStep>属性值id的{​​{1}}。要使用XPath执行此操作,您需要使用语法stepNumber,即:

[@attributeName='attributeValue']

请注意,如果var addStep = doc.XPathSelectElement(string.Format("Content/proceduralStep[@id='{0}']", stepNumber)); 用户输入的字符串,则需要小心阻止XPath injection,例如按照说明{{3} }。

或者,您可以通过附加here表达式来执行此操作:

stepNumber

XPath注入不是这种方法的问题。

(您当前正在调用的方法Where,返回具有指定名称的属性,这是您不想要的。)

然后var addStep = doc.XPathSelectElements("Content/proceduralStep") .Where(e => (string)e.Attribute("id") == stepNumber) .FirstOrDefault(); 需要正确地大写为XElement.Attribute(XName)

add()