473,791 Members | 3,028 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

XmlTextReader Hack

I am trying to use an XmlTextReader to retrieve data. I need to use an
XmlTextReader because it is faster than using an XmlDocument.

I have found an inelegant way of retrieving each item's title and
description using string methods. See my code below. I would like to know how
I can retrieve the <title> and <description> nodes more directly using the
methods of the XmlTextReader.

My xml file looks somthing like:
<items>
<item><title>Ti tle 1</title><descript ion>Description 1</description></item>
<item><title>Ti tle 2</title><descript ion>Description 2</description></item>
</items>

My Hack:
XmlTextReader xmlTextReader = new XmlTextReader(m yXmlUrl);

while(xmlTextRe ader.Read())
{
if(xmlTextReade r.NodeType == XmlNodeType.Ele ment && xmlTextReader.N ame ==
"item" )
{
string itemContent = xmlTextReader.R eadOuterXml();
int headlineStart = itemContent.Ind exOf("<title>") + "<title>".Lengt h;
headlineLength = itemContent.Ind exOf("</title>") - headlineStart;
descriptStart = itemContent.Ind exOf("<descript ion>") +
"<description>" .Length;
int descriptLength = itemContent.Ind exOf("</description>") - descriptStart;
string headline = itemContent.Sub string(headline Start,
headlineLength) ;
string description = itemContent.Sub string(descript Start, descriptLength) ;

Response.Write( headline + "<br>" + description + "<br><br>") ;
}

Many thanks,

CR
Mar 14 '06 #1
4 6025
String manipulation here is a bit messy, but works (I guess);

Personally, I use a bespoke XmlReader-based approach for this that uses a
custom iterator (so only has one "row" in memory at once); I tell it the
name of the parent nodes ("item" in this case) and each *direct* child
("title" and "descriptio n"), and it returns each row as an array matching
what I passed it. It copes with parents at different levels, children in any
order, and elements and attributes (children) - e.g.

foreach(string[] fields in reader.ReadElem ents("item", "title",
"descriptio n")) {
// title is fields[0], description is fields[1]
}

I can post / e-mail the source if you are interested, but it is a bit
long... but it shows a different way to do it (without the strings).

Or you can do it manually in about 20 ways...

Let me know if you want me to post it

Marc

"CodeRazor" <Co*******@disc ussions.microso ft.com> wrote in message
news:E9******** *************** ***********@mic rosoft.com...
I am trying to use an XmlTextReader to retrieve data. I need to use an
XmlTextReader because it is faster than using an XmlDocument.

I have found an inelegant way of retrieving each item's title and
description using string methods. See my code below. I would like to know
how
I can retrieve the <title> and <description> nodes more directly using the
methods of the XmlTextReader.

My xml file looks somthing like:
<items>
<item><title>Ti tle 1</title><descript ion>Description
1</description></item>
<item><title>Ti tle 2</title><descript ion>Description
2</description></item>
</items>

My Hack:
XmlTextReader xmlTextReader = new XmlTextReader(m yXmlUrl);

while(xmlTextRe ader.Read())
{
if(xmlTextReade r.NodeType == XmlNodeType.Ele ment && xmlTextReader.N ame ==
"item" )
{
string itemContent = xmlTextReader.R eadOuterXml();
int headlineStart = itemContent.Ind exOf("<title>") + "<title>".Lengt h;
headlineLength = itemContent.Ind exOf("</title>") - headlineStart;
descriptStart = itemContent.Ind exOf("<descript ion>") +
"<description>" .Length;
int descriptLength = itemContent.Ind exOf("</description>") -
descriptStart;
string headline = itemContent.Sub string(headline Start,
headlineLength) ;
string description = itemContent.Sub string(descript Start, descriptLength) ;

Response.Write( headline + "<br>" + description + "<br><br>") ;
}

Many thanks,

CR

Mar 14 '06 #2
Hi Marc, thanks for your help.

When i tried what you suggested though, i get the error,
"'System.Xml.Xm lTextReader' does not contain a definition for 'ReadElements'"

Are you using an XmlTextReader?

I've sent you an email to your posted address.

Mar 14 '06 #3
no; this is (as stated) using a bespoke class - SimpleXmlReader ; copied
below - use it something like:

using(SimpleXml Reader reader = new SimpleXmlReader ({your chosen ctor})) {
// the code from before
}

Let me know if you have any problems,

Marc
using System;
using System.Xml;
using System.IO;
using System.Collecti ons.Generic;
using System.Text;

namespace Your.Namespace. Xml {
/// <summary>
/// Provides a simple but efficient way of reading typical
/// Xml structures with named (field) attributes or elements
<b>immediatel y</b> underneath
/// named (row) elements
/// </summary>
public sealed class SimpleXmlReader : IDisposable {
private static Dictionary<stri ng, int> GetDictionary(s tring[]
nodeNames) {
int index = 0;
Dictionary<stri ng, int> requiredValues = new Dictionary<stri ng,
int>(nodeNames. Length);
foreach (string nodeName in nodeNames) {
if (!string.IsNull OrEmpty(nodeNam e)) {
// deliberately breaks if duplicated key requested;
value represents
// position in out array
requiredValues. Add(nodeName, index++);
}
}
return requiredValues;
}
/// <summary>
/// Returns the cited node values underneath the current element in
the reader
/// </summary>
/// <param name="reader">T he reader to investigate</param>
/// <param name="nodeNames ">The fields required (prefix attributes
with @)</param>
/// <returns>Arra y of strings, with each value in the corresponding
position to the requested fields</returns>
public static string[] ReadValues(XmlR eader reader, params string[]
nodeNames) {
return ReadValues(read er, GetDictionary(n odeNames));
}
private static string[] ReadValues(XmlR eader reader,
Dictionary<stri ng, int> requiredValues) {
string[] result = new string[requiredValues. Count];
string name;
int index, targetDepth = reader.Depth + 1;
bool isEmpty = reader.IsEmptyE lement;
if(reader.HasAt tributes) {
if (reader.MoveToF irstAttribute() ) { // read attributes
do {
name = "@" + reader.Name;
if (requiredValues .TryGetValue(na me, out index) &&
result[index] == null) {
result[index] = reader.Value;
}
} while (reader.MoveToN extAttribute()) ;
}
}
if (!isEmpty && reader.Read()) {// read sub-elements (note this
progresses the cursor)
while (true) {
int currentDepth = reader.Depth;
if (reader.Depth < targetDepth) {
break; // too shallow: reached end of element
} else if (currentDepth > targetDepth) { // too deep:
only interested in first descendents
reader.Skip();
} else if (reader.NodeTyp e == XmlNodeType.Ele ment) { //
right depth; is it an element?
name = reader.Name;
if (requiredValues .TryGetValue(na me, out index) &&
result[index] == null) {
result[index] =
reader.ReadElem entContentAsStr ing(); // progresses cursor
} else { // not interested
reader.Skip(); // progresses cursor
}
} else if (!reader.Read() ) { // progresses cursor
break; // end of the xml (somehow!)
}
}
}
return result;
}

private Stream _stream;
private readonly bool _leaveStreamOpe n, _leaveReaderOpe n;

/// <summary>
/// Create a SimpleXmlReader from a string
/// </summary>
/// <param name="xmlString ">The xml to load</param>
/// <returns>A new SimpleXmlReader object</returns>
public static SimpleXmlReader Create(string xmlString) {
return new SimpleXmlReader (Encoding.UTF8. GetBytes(xmlStr ing));
}

public SimpleXmlReader (string path) : this(new FileStream(path ,
FileMode.Open), false) { }
public SimpleXmlReader (byte[] data) : this(new MemoryStream(da ta),
false) { }
public SimpleXmlReader (Stream stream) : this(stream, false) { }
public SimpleXmlReader (Stream stream, bool leaveOpen) {
_leaveStreamOpe n = leaveOpen;
_leaveReaderOpe n = false;
_stream = stream;
}
public SimpleXmlReader (XmlReader reader) : this(reader, false) { }
public SimpleXmlReader (XmlReader reader, bool leaveOpen) {
_leaveStreamOpe n = false;
_leaveReaderOpe n = leaveOpen;
_reader = reader;
}
/// <summary>
/// Reads the stream, returning an XmlDocument
/// </summary>
/// <returns>The XmlDocument of the data</returns>
/// <remarks>This will read to the end of the stream, and
/// cannot be repeated</remarks>
public XmlDocument GetDocument() {
XmlDocument doc = new XmlDocument();
if (_stream != null)
doc.Load(_strea m);
else if (_reader != null)
doc.Load(_reade r);
else
throw new InvalidOperatio nException("No stream/reader to
load from");
return doc;
}

private XmlReader _reader;
public XmlReader Reader {
get {
if (_reader == null) {
XmlReaderSettin gs readerSettings = new
XmlReaderSettin gs();
readerSettings. CloseInput = !_leaveStreamOp en;
readerSettings. IgnoreComments = true;
_reader = XmlReader.Creat e(_stream, readerSettings) ;
}
return _reader;
}
}
/// <summary>
/// Searches through the xml (forwards only) looking for the cited
row-element;
/// for each such found, the requested fields are returned to the
caller
/// </summary>
/// <param name="rowElemen tName">The element to search for (at any
level) </param>
/// <param name="nodeNames ">The fields required (prefix attributes
with @)</param>
/// <returns></returns>
/// <remarks>Note that this searches the xml *while* enumerating -
so only one row
/// is ever in memory at once; this makes for highly efficient
processing</remarks>
public System.Collecti ons.Generic.IEn umerable<string[]>
ReadElements(st ring rowElementName, params string[] valueNodeNames) {
XmlReader reader = Reader; // creates if not already there
Dictionary<stri ng, int> requiredValues =
GetDictionary(v alueNodeNames);
while (reader.ReadToF ollowing(rowEle mentName)) {
yield return ReadValues(read er, requiredValues) ;
}

}

public void Close() {
if (_reader != null) {
if (!_leaveReaderO pen) {
_reader.Close() ;
}
_reader = null;
}
if (_stream != null) {
if (!_leaveStreamO pen) {
_stream.Close() ;
_stream.Dispose ();
}
_stream = null;
}
}
public void Dispose() {
Close();
}
}
}

"CodeRazor" <Co*******@disc ussions.microso ft.com> wrote in message
news:9C******** *************** ***********@mic rosoft.com...
Hi Marc, thanks for your help.

When i tried what you suggested though, i get the error,
"'System.Xml.Xm lTextReader' does not contain a definition for
'ReadElements'"

Are you using an XmlTextReader?

I've sent you an email to your posted address.

Mar 14 '06 #4
thanks Marc, but this is too complex for what I need.
All I want to do is just read the values from the title and description
nodes in my xml file using XmlTextReader methods.

How can i do that? -- thanks

<items>
<item><title>Ti tle 1</title><descript ion>Description 1</description></item>
<item><title>Ti tle 2</title><descript ion>Description 2</description></item>
</items>
Mar 15 '06 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
11402
by: Andy Neilson | last post by:
I've run across a strange behaviour with XmlSerializer that I'm unable to explain. I came across this while trying to use XmlSerializer to deserialize from a the details of a SoapException. This should have worked fine since the class in question was already being serialized and deserialized as part of a Web service interface. What I found was that by deserializing from an XmlNodeReader instead of an XmlTextReader, XML Serialization doesn't work...
5
9219
by: Geoff Bennett | last post by:
While parsing an XML document, my TextReader instance skips nodes. For example, in this fragment: <Person Sex="Male" FirstHomeBuyer="No" YearsInCurrentProfession="14"> <RelatedEntityRef RelatedID="118"/> <PersonName> <NameTitle Value="Mr"/> <FirstName>Clint</FirstName> <OtherName/> <AlsoKnownAs>Mr C Eastwood</AlsoKnownAs>
2
4170
by: Yuriy | last post by:
Hi, any ideas how to read XML fragment from TextReader? XmlTextReader constructor accepts only Stream or string as source Do I miss something? thanks Yuriy
1
5460
by: RJN | last post by:
Hi I'm using XMLTextReader to parse the contents of XML. I have issues when the xml content itself has some special characters like & ,> etc. <CompanyName>Johnson & Jhonson</CompanyName> <EmployeeStrength>> 1000</EmployeeStrength> When I do a Xmltextreader.read() and then check the contents of the xml node by XmltextReader.ReadString(), I get an exception when I have
1
2255
by: SHC | last post by:
Hi all, I did the "Build" on the attached code in my VC++ .NET 2003 - Windows XP Pro PC. On the c:\ screen, I got the following: Microsoft Development Environment An unhandled exception of type 'System.Xml.XmlException' occured in system.xml.dll Addtional Information: System error |Break| |Continue| I clicked on the |Continue| and I got the following: "c:\Documents and Settings\Scott H. Chang\My Documents\Visual Studio...
3
1859
by: Kjeld | last post by:
My scenario: I'm using an XmlTextReader to Deserialize serveral classes from a single xml document. Every class i pass the source stream, containing the xml. Each class subsequently creates an XmlTextReader object with that stream as input. However, the second class that performs this operation cannot start reading at position X, because the first instance of XmlTextReader advanced the position in the stream to the end of the stream....
2
2108
by: XML reading with XMLTextReader | last post by:
im trying to read an xml file which is in the wwwroot folder.im using IIS on XP Prof. my code is -------------------------------------------------------------------------------------------------------- <%@ Page Language="VB" Debug="true" codePage="28599" %> <script runat="server"> Sub Page_Load(Sender as Object,E As EventArgs) dim okuyucu as XMLTextReader okuyucu=new XMLTextReader(Server.MapPath("comments.xml"))
4
44965
by: CodeRazor | last post by:
I am reading an xml file from a URL. I was originally doing this using the XmlDocument class. But this was very slow. The XmlTextReader is meant to be much quicker for forward only retrieval of data. I need to somehow access a particular list of nodes. e.g. I want to loop through all the nodes called <item></item>. How is this possible using XmlTextReader? I can see that you can get the .Value property of XmlTextReader. But I want to...
1
1533
by: Steve | last post by:
For some reason, the schema seems to be empty every time it's loaded. Does anyone have any ideas?? Thanks! Here's the code: Dim xsd As System.Xml.Schema.XmlSchema Dim io As New System.IO.FileStream(xsdFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read) Dim x As New System.Xml.XmlTextReader(io) xsd = System.Xml.Schema.XmlSchema.Read(x, New
0
9669
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9995
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9029
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7537
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6776
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5431
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4110
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3718
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2916
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.