Cdata, C# and XML

  • Thread starter Thread starter Logician
  • Start date Start date
L

Logician

Does someone have a link for reading CDATA in C#?

I have the problem that the ReadString method fails. I have tried a
few things but the data is not read correctly.

I would appreciate any help.
 
Logician said:
Does someone have a link for reading CDATA in C#?

I have the problem that the ReadString method fails. I have tried a
few things but the data is not read correctly.

I would appreciate any help.

Could you post a short but complete program which demonstrates the
problem?

See http://www.pobox.com/~skeet/csharp/complete.html for details of
what I mean by that.
 
Could you post a short but complete program which demonstrates the
problem?

Seehttp://www.pobox.com/~skeet/csharp/complete.htmlfor details of
what I mean by that.

Hi Jon
I meant to post the code but I was at home without it. The C# program
is dead simple and just reads the nodes, and it works fine except for
the CDATA. It did work and then suddenly stopped, so I probably
accidently changed it (the original code was two years old). So I am
sure it is a small change needed. The XML file is a data file of
bathroom data and has basic descriptions, images, and comments. There
are about a 1500 files to read and handle, so a program is needed.

I have searched google for relevant data on this and found various
combinations but nothing is really working for me. It is something
related to reading strings, values, attributes. I read several posts
of people having problems in parsing CDATA but the solutions seemed to
be use Value which does not work for me.

The key problems are with farbname (colour in German), kurztext (short
text), and langtext. I decided not to navigate the parent structure
and it seemed to make no difference, and I just used the nodenames.

Here is the code running under .NET 1.1, C#, Windows Forms (under
Windows XP):

<?xml version="1.0" encoding="UTF-16" ?>
- <produkt>
<produktid value="6858651" />
<artnr value="33304" />
<kombipr value="false" />
- <kurztext>
- <![CDATA[ Single-lever bath/shower mixer 1/2"
]]>
</kurztext>
<gewusst_wie value="false" />
- <internettext>
- <![CDATA[
]]>
</internettext>
- <stlb>
- <![CDATA[
]]>
</stlb>
<pid value="6858657" />
<dxf value="/dxf/1074194.zip" />
- <langtext>
- <![CDATA[ metal lever<br>46 mm ceramic cartridge with <br>Eco-
Override-Stop, with <b>GROHE SilkMove®</b><br>adjustable flow rate
limiter<br>adjustable minimum flow rate 2.5 l/min<br>automatic
diverter: bath/shower<br>integrated non-return valves <br>in the
shower outlet 1/2"<br>mousseur aerator (HP)<br>without connection
unions<br>optional temperature limiter<br>protected against
backflow<br>Min. recommended pressure 1.0 bar<br>Balanced hot and cold
supplies
]]>
</langtext>
<mbild value="./images/draw/Z33304001.jpg" online="./images/draw/
online/Z33304001.jpg" width="36" height="60" />
<stbild value="./images/strich/S33304001.gif" online="./images/
strich/online/S33304001.jpg" width="87" height="60" />
<swbild value="./images/sw/F33304001.gif" online="./images/sw/online/
F33304001.jpg" thumbnails="./images/sw/thumbnails/F33304001.jpg" />
<gruppe value="02" />
<designlinie value="05" />
<prodtyp value="05" />
<sge value="02" />
<montage value="01" />
<zapfstelle value="03" />
<linie value="D67" />
<design value="67" />
<brausen value="01" />
- <produktliniename>
- <![CDATA[ PL_Eurosmart
]]>
</produktliniename>
<produktlinienid value="6850046" />
- <produktlinientext>
- <![CDATA[ Eurosmart
]]>
</produktlinientext>
<ranking value="7" />
<pq value="./images/pq/EnglischUK/D33304.gif" online="./images/pq/
online/EnglischUK/D33304.jpg" />
- <farben>
- <farbe>
<produktid value="6858651" />
- <farbname>
- <![CDATA[ chrome
]]>
</farbname>
<schluessel value="001" />
<vvs value="" />
<pbild value="./images/prod/33304001.gif" online="./images/prod/
online/33304001.jpg" thumbnails="./images/prod/thumbnails/
33304001.jpg" />
<ranking value="0" />
<stueckliste value="true" />
<explozeichnung value="./images/explo/E33304001.jpg" online="./
images/explo/online/E33304001.jpg" width="44" height="60" />
<preis value="90.33" />
<preis2 value="" />
</farbe>
</farben>
</produkt>


private void handleGroheXML(string filePath1)
{


// write file
string thisOutFilePath = "c:\\grohe\\xml\\processed.txt";
FileStream fs = new
FileStream(thisOutFilePath,FileMode.Append,FileAccess.Write,FileShare.Write);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine(filePath1);
sw.Close();
// end write file

string thisXMLName="";
filePath1="C:\\grohe\\xml\\"+filePath1;
XmlTextReader reader = new XmlTextReader((filePath1));
reader.WhitespaceHandling=WhitespaceHandling.None;
XmlDocument xmlDoc = new XmlDocument();
int index1 = filePath1.IndexOf(".xml");
if (index1>0)
{
while(reader.Read())
{
//if (reader.NodeType == XmlNodeType.Element)
if (reader.LocalName.Length>0)
{

//////////Trace.Warn("reader.localname top =="+
reader.LocalName);
string thisNodeType = reader.NodeType.ToString();
thisXMLName = reader.LocalName;
if (thisXMLName == "farbname")
{
string xx="";

thisColour = reader.Value;
//string jj1 = reader.LocalName;
string jj="";

thisColour = reader.ReadString();
//thisColour=reader.GetAttribute("CDATA");
thisPOID = handleColour(thisColour);

}

if (thisXMLName == "produktid")
{
string hh1="";
}
if (thisXMLName == "artnr")
{
thisPartNumber = reader.GetAttribute("value");
thisManPartNumber = thisPartNumber;
//string thisNodeType = reader.NodeType.ToString();
//ReadAttributeValue("value");
//string gg="";
}
if (thisXMLName == "kurztext")
{
thisShortDesc = reader.ReadString();
thisShortDesc=thisShortDesc.Replace("<b>","");
thisShortDesc=thisShortDesc.Replace("</b>","");
thisShortDesc=thisShortDesc.Replace("<Normal>","");
thisShortDesc=thisShortDesc.Replace("</Normal>","");

// trevor
thisPartDesc = thisShortDesc;
if (thisShortDesc.Length>50)
{
thisShortDesc = thisShortDesc.Substring(0,50);
}
//string thisNodeType = reader.NodeType.ToString();
//ReadAttributeValue("value");

}
if (thisXMLName == "gruppe")
{
thisFamily = reader.GetAttribute("value");
//string thisNodeType = reader.NodeType.ToString();
//ReadAttributeValue("value");

}
if (thisXMLName == "langtext")
{
thisCommentStr = reader.ReadString();
//string thisNodeType = reader.NodeType.ToString();
//ReadAttributeValue("value");


}
if (thisXMLName == "pbild")
{
// process pbild

}
// get schusell prefix

if (thisXMLName == "mbild")
{
thisSizeImage = reader.GetAttribute("value");
thisSizeImage=thisSizeImage.Replace("./images/draw/","");
}
if (thisXMLName == "stbild")
{
thisLineImage = reader.GetAttribute("value");
thisLineImage=thisLineImage.Replace("./images/strich/","");
}
if (thisXMLName == "swbild")
{
thisOrgPic = reader.GetAttribute("value");
thisOrgPic=thisOrgPic.Replace("./images/sw/","");
}

if (thisXMLName == "explozeichnung")
{
thisInstallationPic = reader.GetAttribute("value");
thisInstallationPic=thisInstallationPic.Replace("./images/
explo/","");
}
if (thisXMLName == "pq")
{
thisFlowRatePic = reader.GetAttribute("value");
thisFlowRatePic=thisFlowRatePic.Replace("./images/pq/","");
thisFlowRatePic=thisFlowRatePic.Replace("./images/prod/","");
}
if (thisXMLName == "produktliniename")
{
thisRange = reader.ReadString();
}

if (thisXMLName == "schluessel")
{
thisPartNumberOption= reader.GetAttribute("value");
}
if (thisXMLName == "preis")
{
string thisPriceS= reader.GetAttribute("value");
// process price




//if (thisXMLName == "farben")
//{
// get farbe record
// reader.ReadStartElement("farbname");
//
// string thisData = reader.ReadString();
//
// reader.ReadEndElement();


//}


}
}
}
}

}
 
Logician said:
I meant to post the code but I was at home without it. The C# program
is dead simple and just reads the nodes, and it works fine except for
the CDATA. It did work and then suddenly stopped, so I probably
accidently changed it (the original code was two years old). So I am
sure it is a small change needed.

I dare say it is, but it's pretty hard to know what the change is
without seeing the code. Please post a short but complete program
(there's no need for hundreds of lines of business-specific code) and
XML file (in true XML, not pasted from IE) so we can reproduce the
problem and fix it.
 
This is sample VB6 code which I wrote to retrieve CDATA node in xml
document using DOM. I am sure there should be something similar

Dim s As String
s = "<a><![CDATA[hello world whats up?]]></a>"

Dim x As New DOMDocument, c As IXMLDOMCDATASection
MsgBox x.loadXML(s)

Set c = x.selectSingleNode("//a").childNodes(0)


Hope this helps
Kalpesh
 
Kalpesh Shah said:
This is sample VB6 code which I wrote to retrieve CDATA node in xml
document using DOM. I am sure there should be something similar

Dim s As String
s = "<a><![CDATA[hello world whats up?]]></a>"

Dim x As New DOMDocument, c As IXMLDOMCDATASection
MsgBox x.loadXML(s)

Set c = x.selectSingleNode("//a").childNodes(0)


Hope this helps

See http://pobox.com/~skeet/csharp/incomplete.html

I hadn't even thinking of putting the question of "Is it in the right
language?" on the list before now.
 
:)

I am sorry about putting example in VB6 (as against c#)
Just what I found quick way to answer the problem using VBA.

Thanks
Kalpesh
 
I dare say it is, but it's pretty hard to know what the change is
without seeing the code. Please post a short but complete program
(there's no need for hundreds of lines of business-specific code) and
XML file (in true XML, not pasted from IE) so we can reproduce the
problem and fix it.

Jon, I have copied pasted some simple code and the xml file below. The
code just reads the xml file in a loop and then tests the node names.
This whole issue is one of the c#/.NET parsing the XML and identifying
the nodes correctly. I have seen some posts suggesting there is a
problem in this matter with c# and XML. The XML file is a real
business file as supplied by the manufacturer of the product line.

The C# debugger clearly shows the data held in the reader object under
CDATAToken and in the Value field but the Value method does not get
the data. It just gets null when used. I have tried other methods like
ReadString and they all fail too when reading CDATA but otherwise they
work on the nodes.

The XML file seems to be valid, so the issue is a c# language one.

If you know how to read CDATA using c# then I would appreciate you
telling me.

<kurztext><![CDATA[Dual control shower mixer 1/2" ]]></
kurztext><gewusst_wie value="false"/><internettext><![CDATA[]]></
internettext><stlb><![CDATA[]]></stlb><pid value="6850218" /><dxf
value="" /><langtext><![CDATA[Thermostatic<br>suitable for high / low
pressure<br>concealed brass body &amp; trim set <br>flow &amp;
temperature control handles<br>wax thermoelement<br>installation
bracket for body<br>built-in non return valve<br>dirt
strainers<br>shower outlet 1/2" top or bottom<br>flow limiters for
high (&gt;1.0bar) or unequal pressures<br>recommended pressure 0.1 -
5.0 bar]]> said:
<stbild value="./images/strich/S3422401.gif" online="./images/strich/
online/S3422401.jpg" width="49" height="60"/><swbild value="./images/
sw/ZZG_34224000_V01_01.gif" online="./images/sw/online/
ZZG_34224000_V01_01.jpg" thumbnails="./images/sw/thumbnails/
ZZG_34224000_V01_01.jpg"/><gruppe value="XX" /><designlinie
value="XX" /><prodtyp value="XX" /><sge value="XX" /><montage
value="XX" /><zapfstelle value="XX" /><linie value="LXX" /><design
value="XX" /><brausen value="XX" /><produktliniename><!
[CDATA[PL_Avensys]]></produktliniename><produktlinienid
value="6850209" /><produktlinientext><![CDATA[Avensys Modern]]></
produktlinientext><ranking value="3" /><pq value="./images/pq/
EnglischUK/D34224.gif" online="./images/pq/online/EnglischUK/
D34224.jpg" /> said:
<pbild value="./images/prod/ZZF_34224000_V01_01.gif" online="./images/
prod/online/ZZF_34224000_V01_01.jpg" thumbnails="./images/prod/
thumbnails/ZZF_34224000_V01_01.jpg"/><ranking value="0"/><stueckliste
value="true"/><explozeichnung value="./images/explo/E3422401.jpg"
online="./images/explo/online/E3422401.jpg" width="92" height="60"/
<preis value="277.49"/><preis2 value=""/></farbe></farben></produkt>

private void sampleXML()
{
string filePath1 = "samplexml.xml";



string thisXMLName="";
filePath1="C:\\grohe\\xml\\"+filePath1;
XmlTextReader reader = new XmlTextReader((filePath1));
reader.WhitespaceHandling=WhitespaceHandling.None;
XmlDocument xmlDoc = new XmlDocument();
int index1 = filePath1.IndexOf(".xml");
if (index1>0)
{
while(reader.Read())
{
//if (reader.NodeType == XmlNodeType.Element)
if (reader.LocalName.Length>0)
{

//////////Trace.Warn("reader.localname top =="+
reader.LocalName);
string thisNodeType = reader.NodeType.ToString();
thisXMLName = reader.LocalName;
if (thisXMLName == "farbname")
{
string xx="";

string thisColour = reader.Value;
//string jj1 = reader.LocalName;
string jj="";

thisColour = reader.ReadString();
string gg2 = reader.NodeType.ToString();
//thisColour=reader.GetAttribute("CDATA");

}

if (thisXMLName == "produktid")
{
string hh1="";
}
if (thisXMLName == "artnr")
{
string thisPartNumber = reader.GetAttribute("value");

}
if (thisXMLName == "kurztext")
{
string thisShortDesc = reader.ReadString();


}
if (thisXMLName == "gruppe")
{
string thisFamily = reader.GetAttribute("value");


}
if (thisXMLName == "langtext")
{
string thisCommentStr = reader.ReadString();


}
if (thisXMLName == "pbild")
{
string thisPicName = reader.GetAttribute("value");



}
// get schusell prefix

if (thisXMLName == "mbild")
{
string thisSizeImage = reader.GetAttribute("value");

}
if (thisXMLName == "stbild")
{
string thisLineImage = reader.GetAttribute("value");
}
if (thisXMLName == "swbild")
{
string thisOrgPic = reader.GetAttribute("value");
}

if (thisXMLName == "explozeichnung")
{
string thisInstallationPic = reader.GetAttribute("value");
}
if (thisXMLName == "pq")
{
string thisFlowRatePic = reader.GetAttribute("value");
}
if (thisXMLName == "produktliniename")
{
string thisRange = reader.ReadString();
}

if (thisXMLName == "schluessel")
{
string thisPartNumberOption= reader.GetAttribute("value");
}
if (thisXMLName == "preis")
{
string thisPriceS= reader.GetAttribute("value");



}
}
}
}

}
 
This is sample VB6 code which I wrote to retrieve CDATA node in xml
document using DOM. I am sure there should be something similar

Dim s As String
s = "<a><![CDATA[hello world whats up?]]></a>"

Dim x As New DOMDocument, c As IXMLDOMCDATASection
MsgBox x.loadXML(s)

Set c = x.selectSingleNode("//a").childNodes(0)

Hope this helps
Kalpesh

I only use c#. You state that CDATA is a node, but I think it is not a
node. Microsoft calls CDATA a section. This difference is the problem
with reading the data in c#.

See http://msdn2.microsoft.com/en-us/library/ms256076.aspx for more on
CDATA. CDATA was used as the data has HTML in it (eg <br>). The node
names are langtext for example, which the c# parser can identify. The
only problem is therefore extracting the data from what is held in
object. That just needs the right method.
 
Jon, I have copied pasted some simple code and the xml file below.

Well, the code was neither short but complete, but never mind...

You're calling XmlReader.ReadString() but then ignoring the result. If
you look at the value of thisColour in your farbname block (the second
value you assign, not the first) you'll find it's "chrome" which I
assume is what you wanted.
 
Well, the code was neither short but complete, but never mind...

You're calling XmlReader.ReadString() but then ignoring the result. If
you look at the value of thisColour in your farbname block (the second
value you assign, not the first) you'll find it's "chrome" which I
assume is what you wanted.

This still will not work for me. I am debugging and hence I had
different assigns (they are stopped in the debugger).

I will pay a reasonable fee for someone to work this out, are you
interested? I am only trying to read the CDATA section in C# and that
is all. My assignment is therefore to read the XML file provided and
be able to store the data in string fields. I will then do the rest.

Are there any website where I can pay someone for a short task like
this?
 
Logician said:
This still will not work for me. I am debugging and hence I had
different assigns (they are stopped in the debugger).

I will pay a reasonable fee for someone to work this out, are you
interested? I am only trying to read the CDATA section in C# and that
is all. My assignment is therefore to read the XML file provided and
be able to store the data in string fields. I will then do the rest.

What exactly is the problem? Do you get an error, or does your code not
find the data you are looking for?
If you use XmlReader and want to read an element contents like that of
<farbname><![CDATA[chrome]]></farbname>
then you can Read() till you find a node of XmlNodeType.Element and
LocalName == "farbname", then you can use ReadString() to read out the
contents. Accessing the Value property of the XmlReader does not make
sense for element nodes, it is empty.
 
Logician said:
This still will not work for me. I am debugging and hence I had
different assigns (they are stopped in the debugger).

In that case you need to give us a short but complete program which
will actually show the problem. You gave some incomplete code, but
having made it complete I explained how to make it work. Beyond this,
it's impossible to help you if you can't make the code complete.
Changing code in the debugger doesn't help us - producing a short but
complete program would.

This isn't a matter of money, it's a matter of you giving us
appropriate information.
I will pay a reasonable fee for someone to work this out, are you
interested? I am only trying to read the CDATA section in C# and that
is all.

And it works absolutely fine with the modifications I explained. If you
want to produce some code which is complete but *doesn't* work, that's
fine. See http://pobox.com/~skeet/csharp/complete.html for more on what
I mean about that - but it shouldn't involve stopping in the debugger.
 
In that case you need to give us a short but complete program which
will actually show the problem. You gave some incomplete code, but
having made it complete I explained how to make it work. Beyond this,
it's impossible to help you if you can't make the code complete.
Changing code in the debugger doesn't help us - producing a short but
complete program would.

I posted a bid at RentACoder; I hope that will help me.

It could be operating systems settings, or .NET settings which are
causing the issue. I am using Windows Forms and .NET 1.1. The
"complete" program is just simply using the method to read the XML.
You can just copy paste the method into any Windows Forms program
using XML and use the method on an event (eg a button).
 
Logician said:
I posted a bid at RentACoder; I hope that will help me.

It won't unless you can ask the question in a more useful way.
It could be operating systems settings, or .NET settings which are
causing the issue. I am using Windows Forms and .NET 1.1. The
"complete" program is just simply using the method to read the XML.

And I told you how to fix it.
You can just copy paste the method into any Windows Forms program
using XML and use the method on an event (eg a button).

I did that (except into a console app) and made the changes I told you
about. It worked. You then complained about something to do with the
debugger, although it wasn't terribly clear what was going on.

This is why it's important to make the app short and *complete*. There
should be no messing around required in the debugger. Just show a
complete program which does the wrong thing, and we can show you a
program which does the right thing. Anything else is just wasting time.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top