#xml #vb.net
#xml #vb.net
Вопрос:
Dim doc As New XmlDocument()
Dim nodes As XmlNodeList
doc.Load("test.xml")
nodes = doc.SelectNodes("/Subjects/" amp; comboSubject.Text)
Dim fileName As String = IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "test.xml")
Dim Rows As List(Of DataGridViewRow) =
gridTests.Rows.Cast(Of DataGridViewRow).Where(Function(row) Not row.IsNewRow).ToList
Dim xmlData As String =
<<%= comboSubject.Text %>>
<%= From row In Rows
Select
<attempt>
<test><%= CStr(row.Cells("Test").Value) %></test>
<score><%= CStr(row.Cells("Score").Value) %></score>
</attempt> %>
</>.ToString
For Each node As XmlNode In nodes
If node IsNot Nothing Then
node.ParentNode.RemoveChild(node)
doc.Save("test.xml")
End If
Next
Как мне записать строку xmlData в узел Subjects?
<?xml version="1.0" encoding="UTF-8"?>
<Subjects>
<History>
<attempt>
<test>1999</test>
<score>75</score>
</attempt>
<attempt>
<test>1987</test>
<score>50</score>
</attempt>
<attempt>
<test>1789</test>
<score>25</score>
</attempt>
</History>
</Subjects>
Всякий раз, когда я пытаюсь записать строку XmlData в test.xml в итоге либо все удаляется, либо вообще ничего не делается. Я не уверен, что я здесь делаю не так. Любое решение этой проблемы было бы очень оценено.
Ответ №1:
Я вижу несколько проблем…
Dim xmlData As String =
<<%= comboSubject.Text %>>
<%= From row In Rows
Select
<attempt>
<test><%= CStr(row.Cells("Test").Value) %></test>
<score><%= CStr(row.Cells("Score").Value) %></score>
</attempt> %>
</>.ToString
Похоже, что это не приводит к созданию допустимого XML, поскольку тег закрыт неправильно. Это должно быть, например, </History>
вместо </>
Кроме того, вы ничего не делаете с этим XML, кроме как сохраняете его в переменной xmlData. Переменная никогда не используется. Вы продолжаете удалять только существующий узел, вот почему вы видите надпись «удалить все»
For Each node As XmlNode In nodes
If node IsNot Nothing Then
node.ParentNode.RemoveChild(node)
doc.Save("test.xml")
End If
Next
doc
представляет весь ваш документ и node
было бы, например, так, /Subjects/History
поэтому, когда вы говорите, что node.ParentNode.RemoveChild(node)
вы удаляете History
узел из его родительского Subjects
узла, оставляя вам только <Subjects/>
сохраняемый. Этот цикл также вызывал бы save для каждой итерации, в которой нет необходимости, но это ни здесь, ни там.
Наконец, как упоминалось, вы нигде не записываете xmlData
обратно в документ. Не существует отличного ответа на вопрос, как это сделать, потому что XML не предназначен для создания в виде строки таким образом. Вы можете использовать XmlNode.Свойство InnerXml напрямую изменять разметку элемента, но, как отмечает Microsoft в документе, это не лучшая идея. Вы также могли бы разобрать эту строку в объект XML, но в идеале вы должны просто создавать объекты узла для каждого из создаваемых вами элементов, а затем добавлять их в doc
в соответствующем месте. Что-то вроде этого, в качестве примера:
Dim objHistory as XmlElement = doc.CreateElement("History")
Dim objAttempt As XmlElement = doc.CreateElement("attempt")
Dim objTest As XmlElement = doc.CreateElement("test")
Dim objScore as XmlElement = doc.CreateElement("score")
objTest.InnerText = "1999"
objScore.InnerText = "75"
objAttempt.AppendChild(objTest)
objAttempt.AppendChild(objScore)
objHistory.AppendChild(objAttempt)
doc.FirstChild.AppendChild(objHistory)