How to remove an Element/node from XmlDocument ?
-
Wednesday, July 09, 2008 11:22 AM
Hi!
I want to remove the <ProductionExtract> and </Productionextract> tag from my xml below, how can i do this?
<
ProductionExtract><Region Region="North">
<MonthToDate>
<ProductionSteel>0</ProductionSteel>
</MonthToDate>
<YearToDate>
<ProductionSteel>0</ProductionSteel>
</YearToDate>
</Region>
</ProductionExtract>
I try to do the following in VB.NET, but that removed the whole of my XML!
Dim
xmlString As String = ProductionExtractDS.GetXml() Dim xmlDoc As New XmlDocument()xmlDoc.LoadXml(xmlString)
Dim node As XmlNode = xmlDoc.SelectSingleNode("ProductionExtract")node.ParentNode.RemoveChild(node)
So, is there a way to do this?
All Replies
-
Wednesday, July 09, 2008 11:53 AM
Well first of all you don't remove tags, you remove elements or attributes or comments or text nodes.
As for removing the ProductionExtract element but keeping its contents, that is easily possible in your sample above as the element has just one child element, the one Region element. But what do you want to do if there are several child elements? In that case it is not clear what would become the new root element.
Anyway, if you want to remove the ProductionExtract element and make its first child element, the Region element, the new root element, then you can achieve that with the DOM as follows:
Code SnippetDim doc As XmlDocument = New XmlDocument()doc.Load(
"..\..\XMLFile1.xml")doc.ReplaceChild(doc.DocumentElement.SelectSingleNode(
"Region"), doc.DocumentElement)doc.Save(Console.Out)
You could also consider an XSLT stylesheet as follows:
Code Snippet<
xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><
xsl:template match="@* | node()"><
xsl:copy><
xsl:apply-templates select="@* | node()"/></
xsl:copy></
xsl:template><
xsl:template match="/ProductionExtract"><
xsl:apply-templates/></
xsl:template></
xsl:stylesheet>
Such a transformation could be executed with System.Xml.Xsl.XslCompiledTransform. -
Thursday, July 10, 2008 6:52 AM
Thanx
That worked like a charm! (using DOM)
As I do more and more regions my xml now looks like this:
<Region Region="North">
<MonthToDate>
<ProductionSteel>0</ProductionSteel>
</MonthToDate>
<YearToDate>
<ProductionSteel>0</ProductionSteel>
</YearToDate>
</Region>
<Region Region="South">
<MonthToDate>
<ProductionSteel>0</ProductionSteel>
</MonthToDate>
<YearToDate>
<ProductionSteel>0</ProductionSteel>
</YearToDate>
</Region>
This is the code for creating that (looping for each region) - as you can see the DsToXmlString stringbuilder gets filled with each region:
Dim xmlString As String = ProductionExtractDS.GetXml() Dim xmlDoc As New XmlDocument()xmlDoc.LoadXml(xmlString)
xmlDoc.ReplaceChild(xmlDoc.DocumentElement.SelectSingleNode(
"Region"), xmlDoc.DocumentElement)
Dim stringWriter As New System.IO.StringWriter Dim xmlWriter As New XmlTextWriter(stringWriter)xmlWriter.Formatting = Formatting.Indented
xmlDoc.WriteTo(xmlWriter)
DsToXmlString.Append(stringWriter.ToString())
What I want to do now is to add the <ProductionExtract> element around the whole of this - causing the xml to look like this:
<ProductionExtract>
<Region Region="North">
<MonthToDate>
<ProductionSteel>0</ProductionSteel>
</MonthToDate>
<YearToDate>
<ProductionSteel>0</ProductionSteel>
</YearToDate>
</Region>
<Region Region="South">
<MonthToDate>
<ProductionSteel>0</ProductionSteel>
</MonthToDate>
<YearToDate>
<ProductionSteel>0</ProductionSteel>
</YearToDate>
</Region>
<ProductionExtract>
Is there an easy way to add inn this element and to make it indent to do this ?
Thanx in advance!
-
Thursday, July 10, 2008 12:40 PM
I would not use strings and/or StringWriters or StringBuilders to construct XML as the .NET framework has better APIs to construct XML, there is XmlWriter and there is XmlDocument, that should suffice and makes sure the result is well-formed, something that string concatenation or StringWriter/Builder use does not ensure.
Thus if you want to construct the XML you posted then you could easily construct it all using XmlWriter or XmlDocument.
-
Thursday, July 10, 2008 12:47 PM
I've used XMLDocument for most part of my xml - but for adding this top level thingy I've used stringbuilders as a quick solution - although using XmlWriter probably is what I should have done.
Thanx for the help so far!
I have my complete constructed XML now and it's well formed and validates against my XSD when I use XMLSpy.
What i now want to do is validate the xml against the schema within my VB code. Do you have a good tip on how to do that - lets try to keep it as simple as possible..

-
Thursday, July 10, 2008 1:07 PM
If you use .NET 2.0 or later and have a System.Xml.XmlDocument then you can use the Validate method http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.validate.aspx
so you would add schemas to the Schemas property and then call the Validate method, passing in your ValidationEventHandler that will then be called to report any validation errors:
Code SnippetDim doc As New XmlDocument()
' create and insert nodes here, then
doc.Schemas.Add(Nothing, "schema1.xsd")
' add further schemas if needed here, then
doc.Validate(yourValidationEventHandler)
If you have an XML file then you don't need an System.Xml.XmlDocument, you can simply use an XmlReader with proper XmlReaderSettings to perform the validation.
-
Thursday, July 10, 2008 1:59 PM
Thanx again!

So this is my code, but I never get to the handler even though I have error which i manually put into the xml:
This is the code I use:
Public
Sub ValidateXmlAgainstSchema(ByVal XmlString As String)
Dim xmlDocToValidate As New XmlDocument Dim test As New XmlExtractsxmlDocToValidate.LoadXml(DsToXmlString.ToString)
xmlDocToValidate.Schemas.Add("", "C:\ProductionDataExtract.XSD")
Dim eventHandler As ValidationEventHandler = New ValidationEventHandler(AddressOf test.ValidationEventHandler)
xmlDocToValidate.Validate(eventHandler)
End Sub
Public Sub ValidationEventHandler(ByVal sender As Object, ByVal e As ValidationEventArgs)
Select Case e.Severity
Case XmlSeverityType.ErrorDebug.WriteLine(
"Error: {0}", e.Message) Case XmlSeverityType.WarningDebug.WriteLine(
"Warning {0}", e.Message) End Select End SubBut I put breakpoint inside ValidationEventHandler - but doesnt get there - just bumps out saying
"ProductionDataExtract' start tag on line 1 does not match the end tag of 'ProductionDataExtractERRORTEST'" in the output window.
So...any tip of what im doing wrong?
-
Thursday, July 10, 2008 2:22 PM
Well the error you get is a well-formedness error that is found earlier when you do the LoadXml(). The Validate method finds only validation errors, once you have an XmlDocument set up.
So somehow your string concatenation is not producing well-formed XML.
-
Friday, July 11, 2008 11:21 AM
Thanx!
Ok, got fixed now well formed.
Also validation now works with hardcoded path to XSD - trying to embedd the xsd but have some problems using it.
Will create seperate thread for that issue.

