471,594 Members | 1,955 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,594 software developers and data experts.

Navigate and/or update an existing XML file

Hi all,

I'm new to .NET and XML and I have a question. Given an XML file, I want to
navigate its content and look for one or two particular elements to get their
values. At this point, it suffices to open the XML file for read-only access.

Once I have processed these values, I might need to update a bunch of
subelements of a certain element. For example, I may need to update the
Field Name attribute plus the DataField element value in Fields.

<Fields>
<Field Name="EMPLOYEE_ID">
<DataField>EMPLOYEE_ID</DataField>
<rd:TypeName>System.Int64</rd:TypeName>
</Field>
<Field Name="LAST_NAME">
<DataField>LAST_NAME</DataField>
<rd:TypeName>System.String</rd:TypeName>
</Field>
<Field Name="FIRST_NAME">
<DataField>FIRST_NAME</DataField>
<rd:TypeName>System.String</rd:TypeName>
</Field>
</Fields>

The thing is that I may not need to update this XML file. However, when I
need to, this XML file may be big and my question is whether I should use
XmlDocument for read and write purpose together with XPath expressions? Or
should I use XPathDocument for better performance?

Any other suggestions or ideas?

Thank you very much!
Nov 12 '05 #1
8 5656
Hello!
The thing is that I may not need to update this XML file. However, when I
need to, this XML file may be big and my question is whether I should use
XmlDocument for read and write purpose together with XPath expressions? Or
should I use XPathDocument for better performance?


That depends. XmlDocument is the slowest way to do it - if you are able
to do it using XPath & read-only, use XPathDocument. But if the file is
/really/ big (some MBytes) it's best to use XmlTextReader - it is not as
flexible as evaluating a simple XPath expression but the fastest way
(and your document does not look that complex - it should be easy)

<http://msdn2.microsoft.com/library/System.Xml.XmlTextReader>

If you need fast reading & writing and the data you edit does not depend
on anything else in the document (like "change last name of employee
42") you can use XmlTextReader and XmlTextWriter to "stream process" the
document:

<http://msdn2.microsoft.com/library/System.Xml.XmlTextWriter>
This could look like this (untested):

\\\

XmlTextReader r = new XmlTextReader("file");
XmlTextWriter w = new XmlTextWriter("tempfile");

string id = "42";
bool isField, isEmployeeFieldm, isTargetDataField, isTargetEmployee;

while( r.Read() ){
switch( r.NodeType ){
...
case XmlNodeType.Element:
isField = r.LocalName.Equals( "Field" );
w.WriteStartElement( r.Name );
isTargetDataField = isEmployeeField &&
r.LocalName.Equals("DataField");
break;
...
case XmlNodeType.Attribute:
isEmployeeField = isField && r.LocalName.Equals("Name") &&
r.Value.Equals("EMPLOYEE_ID");
w.WriteStartAttribute( r.Name );
break;
...
case XmlNodeType.Text:
isTargetEmployee = isTargetDataField && r.Value.Equals("42");
....

}
}

///

--
Pascal Schmitt
Nov 12 '05 #2
Thank you for your help! Really appreciated!

The thing is that it is not always read-only access and the file may be a
few hundred kilo bytes. I'm not sure how slow XmlDocument can be.

Would you recommend that I simply use XmlTextReader to search for some
elements while reading in the file instead of using XPath and/or
XPathDocument? Then when I realize that I need to update the Xml file,
simply create a new Xml file using XmlTextWriter?

What I'm worried is that what I need to read (parse) first is near the end
of the Xml file and what I need to update is actually near the top of the Xml
file ...

Any suggestions are welcome. Thank you!
"Pascal Schmitt" wrote:
Hello!
The thing is that I may not need to update this XML file. However, when I
need to, this XML file may be big and my question is whether I should use
XmlDocument for read and write purpose together with XPath expressions? Or
should I use XPathDocument for better performance?


That depends. XmlDocument is the slowest way to do it - if you are able
to do it using XPath & read-only, use XPathDocument. But if the file is
/really/ big (some MBytes) it's best to use XmlTextReader - it is not as
flexible as evaluating a simple XPath expression but the fastest way
(and your document does not look that complex - it should be easy)

<http://msdn2.microsoft.com/library/System.Xml.XmlTextReader>

If you need fast reading & writing and the data you edit does not depend
on anything else in the document (like "change last name of employee
42") you can use XmlTextReader and XmlTextWriter to "stream process" the
document:

<http://msdn2.microsoft.com/library/System.Xml.XmlTextWriter>
This could look like this (untested):

\\\

XmlTextReader r = new XmlTextReader("file");
XmlTextWriter w = new XmlTextWriter("tempfile");

string id = "42";
bool isField, isEmployeeFieldm, isTargetDataField, isTargetEmployee;

while( r.Read() ){
switch( r.NodeType ){
...
case XmlNodeType.Element:
isField = r.LocalName.Equals( "Field" );
w.WriteStartElement( r.Name );
isTargetDataField = isEmployeeField &&
r.LocalName.Equals("DataField");
break;
...
case XmlNodeType.Attribute:
isEmployeeField = isField && r.LocalName.Equals("Name") &&
r.Value.Equals("EMPLOYEE_ID");
w.WriteStartAttribute( r.Name );
break;
...
case XmlNodeType.Text:
isTargetEmployee = isTargetDataField && r.Value.Equals("42");
....

}
}

///

--
Pascal Schmitt

Nov 12 '05 #3
Hello!
Would you recommend that I simply use XmlTextReader to search for some
elements while reading in the file instead of using XPath and/or
XPathDocument? Then when I realize that I need to update the Xml
file,
simply create a new Xml file using XmlTextWriter?
No - the XmlReaders are not caching - you have to use the information
when you read it (if you don't save it on your own) if you want to
"skip" back to the beginning of a file you have to read it from the
beginning with a new XmlReader.

The thing is that it is not always read-only access and the file may
be a
few hundred kilo bytes. I'm not sure how slow XmlDocument can be.

What I'm worried is that what I need to read (parse) first is near the
end
of the Xml file and what I need to update is actually near the top of
the Xml
file ...


The "slow" bit of XmlDocument is that it parses the XML completely and
creates a full DOM-Tree in-memory. This is no problem, if your file is
just in the area of KBytes and you nead Random access.
So for your case I would recommend you to use XmlDocument with its
XPath-abilities for more flexibility and shorter Code (untested):

XmlDocument doc = new XmlDocument();
doc.Load("file");
XmlElement e =
doc.SelectSingleNode("/Fields/Field[@Name='EMPLOYEE_ID']/DataField[.='42']")
as XmlElement;
if( e == null ) throw new Exception();
XmlElement n =
doc.SelectSingleNode("/Fields/Field[@Name='FIRST_NAME']/DataField") as
XmlElement;
if( n == null ) throw new Excepttion();

// do something with the nodes

doc.Save("file");

--
Pascal Schmitt
Nov 12 '05 #4
Your help and sample code are greatly appreciated and I will go ahead
experimenting with XmlDocument and XPath as suggested.

Thank you!
Jenny

"Pascal Schmitt" wrote:
Hello!
> Would you recommend that I simply use XmlTextReader to search for some
> elements while reading in the file instead of using XPath and/or
> XPathDocument? Then when I realize that I need to update the Xml
> file,
> simply create a new Xml file using XmlTextWriter?


No - the XmlReaders are not caching - you have to use the information
when you read it (if you don't save it on your own) if you want to
"skip" back to the beginning of a file you have to read it from the
beginning with a new XmlReader.

> The thing is that it is not always read-only access and the file may
> be a
> few hundred kilo bytes. I'm not sure how slow XmlDocument can be.
>
> What I'm worried is that what I need to read (parse) first is near the
> end
> of the Xml file and what I need to update is actually near the top of
> the Xml
> file ...


The "slow" bit of XmlDocument is that it parses the XML completely and
creates a full DOM-Tree in-memory. This is no problem, if your file is
just in the area of KBytes and you nead Random access.
So for your case I would recommend you to use XmlDocument with its
XPath-abilities for more flexibility and shorter Code (untested):

XmlDocument doc = new XmlDocument();
doc.Load("file");
XmlElement e =
doc.SelectSingleNode("/Fields/Field[@Name='EMPLOYEE_ID']/DataField[.='42']")
as XmlElement;
if( e == null ) throw new Exception();
XmlElement n =
doc.SelectSingleNode("/Fields/Field[@Name='FIRST_NAME']/DataField") as
XmlElement;
if( n == null ) throw new Excepttion();

// do something with the nodes

doc.Save("file");

--
Pascal Schmitt

Nov 12 '05 #5
Hi Pascal

I've played with XmlDocument and XPath expressions and I seem to get what I
wanted so far. Thanks for your help again.

However, as I reach an Xml node and I'd like to create a new Xml element
with attribute and a child element, I do the followings:

XmlElement fieldElem = myXmlDocument.CreateElement("Field");
XmlElement dataField = myXmlDocument.CreateElement("DataField");
XmlText text = myXmlDocument.CreateTextNode("Field 1");
fieldElem.AppendChild(dataField);
dataField.AppendChild(text);
fields.AppendChild(fieldElem);

fieldElem.SetAttribute("Name", "Field 1");

------------

The XML file shows

<Field Name="Field 1" xmlns="">
<DataField>Field 1</DataField>
</Field>
Is there any way that I could get rid of the xmlns part? In other words I
want it to be just <Field Name="Field 1"> ... </Field>

I found that if I call SetAttribute() for an existing Xml element, it does
not add this annoying xmlns part. For some reasons, in my case, I can't seem
to get rid of it.

Please help! Thanks again!
Jenny

"Pascal Schmitt" wrote:
Hello!
> Would you recommend that I simply use XmlTextReader to search for some
> elements while reading in the file instead of using XPath and/or
> XPathDocument? Then when I realize that I need to update the Xml
> file,
> simply create a new Xml file using XmlTextWriter?


No - the XmlReaders are not caching - you have to use the information
when you read it (if you don't save it on your own) if you want to
"skip" back to the beginning of a file you have to read it from the
beginning with a new XmlReader.

> The thing is that it is not always read-only access and the file may
> be a
> few hundred kilo bytes. I'm not sure how slow XmlDocument can be.
>
> What I'm worried is that what I need to read (parse) first is near the
> end
> of the Xml file and what I need to update is actually near the top of
> the Xml
> file ...


The "slow" bit of XmlDocument is that it parses the XML completely and
creates a full DOM-Tree in-memory. This is no problem, if your file is
just in the area of KBytes and you nead Random access.
So for your case I would recommend you to use XmlDocument with its
XPath-abilities for more flexibility and shorter Code (untested):

XmlDocument doc = new XmlDocument();
doc.Load("file");
XmlElement e =
doc.SelectSingleNode("/Fields/Field[@Name='EMPLOYEE_ID']/DataField[.='42']")
as XmlElement;
if( e == null ) throw new Exception();
XmlElement n =
doc.SelectSingleNode("/Fields/Field[@Name='FIRST_NAME']/DataField") as
XmlElement;
if( n == null ) throw new Excepttion();

// do something with the nodes

doc.Save("file");

--
Pascal Schmitt

Nov 12 '05 #6
Hi Jenny,

The xmlns field indicates the default namespace for this field. Since you
didn't set the namespace for this field, and the parent node namespace is
set, the xmlns is automatically generated to indicate the default namespace
for this field is empty.

You can specify the qualified name and namespace URI for the element when
creating like the following.

XmlElement fieldElem = myXmlDocument.CreateElement("Field",
"www.parentnodens.com");

If the namespace "www.parentnodens.com" is the same as parent node
namespace, the xmlns will be omit automantically.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Nov 12 '05 #7
Thanks, Kevin. I actually figured it out myself right after I posted my
problem. Thanks anyway though because this confirms what I think. :-)

Jenny
"Kevin Yu [MSFT]" wrote:
Hi Jenny,

The xmlns field indicates the default namespace for this field. Since you
didn't set the namespace for this field, and the parent node namespace is
set, the xmlns is automatically generated to indicate the default namespace
for this field is empty.

You can specify the qualified name and namespace URI for the element when
creating like the following.

XmlElement fieldElem = myXmlDocument.CreateElement("Field",
"www.parentnodens.com");

If the namespace "www.parentnodens.com" is the same as parent node
namespace, the xmlns will be omit automantically.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Nov 12 '05 #8
You're welcome, Jenny.

Kevin Yu
=======
"This posting is provided "AS IS" with no warranties, and confers no
rights."

Nov 12 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

16 posts views Thread by Philip Boonzaaier | last post: by
2 posts views Thread by Doug Bell | last post: by
2 posts views Thread by Ryan Ramsey | last post: by
reply views Thread by XIAOLAOHU | last post: by
reply views Thread by Anwar ali | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.