我正在尝试从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;
}
}
}
答案 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()