How to "Reach" content of an XML node/tag (and turn it into a new reader)
-
I have a project that will end up language dependent. I am also fairly new to XML in terms of reading it from files. I need to use XML for information used by the project and that information will be available in several languages. So the basic structure of the XML is this:
SomeName SN Some Description of what this represents
The code that does this and then the code that deserializes the information is this:
public static DataClassNode Deserialize(XmlReader reader, CultureInfo culturalLanguage)
{
XmlReader found = null;
XmlReader _default = null;
while (found == null)
{
if (reader.ReadToFollowing("Language"))
{
if (reader.MoveToAttribute("ID"))
{
string id = reader.ReadContentAsString();
reader.MoveToElement(); // Is this how I get to the contents of the language node?
if (id.Equals(culturalLanguage.Name))
{
// not sure how to read the contents of the node
found = XmlReader.Create(reader.ReadElementContentAsString()); // throws exception
// 'Element' is an
// invalid XML Node Type
}
else if (id.Equals(DefaultCulture.Name))
{
_default = XmlReader.Create(reader.ReadInnerXml().ToStream());
}
}
}
else
break;
}
if (found == null)
{
if (_default == null)
throw new Exception("Default Language Not Found!");
else
found = _default;
}DataContractSerializer serializer = new DataContractSerializer(typeof(DataClassNode)); DataClassNode flagtag = (DataClassNode)serializer.ReadObject(found); if (flagtag == null) throw new Exception("Cannot deserialize DataClassNode Object!"); return flagtag;
}
I have been able to navigate to the language and make sure the one needed is found. Now I need to populate a class instance with the data inside the language node. I am using DataContractSerializer so I want a new XMLreader instance that contains the content of the language node ONLY. Not sure how to do this though. I know how to read strings etc... just not sure how to read the contents of the language node. I have tried what is above. I have tried InnerXML and OuterXML. Both of these return "None" as my XML. My comments point to where my knowledge falls short.
-
I have a project that will end up language dependent. I am also fairly new to XML in terms of reading it from files. I need to use XML for information used by the project and that information will be available in several languages. So the basic structure of the XML is this:
SomeName SN Some Description of what this represents
The code that does this and then the code that deserializes the information is this:
public static DataClassNode Deserialize(XmlReader reader, CultureInfo culturalLanguage)
{
XmlReader found = null;
XmlReader _default = null;
while (found == null)
{
if (reader.ReadToFollowing("Language"))
{
if (reader.MoveToAttribute("ID"))
{
string id = reader.ReadContentAsString();
reader.MoveToElement(); // Is this how I get to the contents of the language node?
if (id.Equals(culturalLanguage.Name))
{
// not sure how to read the contents of the node
found = XmlReader.Create(reader.ReadElementContentAsString()); // throws exception
// 'Element' is an
// invalid XML Node Type
}
else if (id.Equals(DefaultCulture.Name))
{
_default = XmlReader.Create(reader.ReadInnerXml().ToStream());
}
}
}
else
break;
}
if (found == null)
{
if (_default == null)
throw new Exception("Default Language Not Found!");
else
found = _default;
}DataContractSerializer serializer = new DataContractSerializer(typeof(DataClassNode)); DataClassNode flagtag = (DataClassNode)serializer.ReadObject(found); if (flagtag == null) throw new Exception("Cannot deserialize DataClassNode Object!"); return flagtag;
}
I have been able to navigate to the language and make sure the one needed is found. Now I need to populate a class instance with the data inside the language node. I am using DataContractSerializer so I want a new XMLreader instance that contains the content of the language node ONLY. Not sure how to do this though. I know how to read strings etc... just not sure how to read the contents of the language node. I have tried what is above. I have tried InnerXML and OuterXML. Both of these return "None" as my XML. My comments point to where my knowledge falls short.
I think you should be using "XPath navigation". [Select Nodes Using XPath Navigation | Microsoft Learn](https://learn.microsoft.com/en-us/dotnet/standard/data/xml/select-nodes-using-xpath-navigation)
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
-
I have a project that will end up language dependent. I am also fairly new to XML in terms of reading it from files. I need to use XML for information used by the project and that information will be available in several languages. So the basic structure of the XML is this:
SomeName SN Some Description of what this represents
The code that does this and then the code that deserializes the information is this:
public static DataClassNode Deserialize(XmlReader reader, CultureInfo culturalLanguage)
{
XmlReader found = null;
XmlReader _default = null;
while (found == null)
{
if (reader.ReadToFollowing("Language"))
{
if (reader.MoveToAttribute("ID"))
{
string id = reader.ReadContentAsString();
reader.MoveToElement(); // Is this how I get to the contents of the language node?
if (id.Equals(culturalLanguage.Name))
{
// not sure how to read the contents of the node
found = XmlReader.Create(reader.ReadElementContentAsString()); // throws exception
// 'Element' is an
// invalid XML Node Type
}
else if (id.Equals(DefaultCulture.Name))
{
_default = XmlReader.Create(reader.ReadInnerXml().ToStream());
}
}
}
else
break;
}
if (found == null)
{
if (_default == null)
throw new Exception("Default Language Not Found!");
else
found = _default;
}DataContractSerializer serializer = new DataContractSerializer(typeof(DataClassNode)); DataClassNode flagtag = (DataClassNode)serializer.ReadObject(found); if (flagtag == null) throw new Exception("Cannot deserialize DataClassNode Object!"); return flagtag;
}
I have been able to navigate to the language and make sure the one needed is found. Now I need to populate a class instance with the data inside the language node. I am using DataContractSerializer so I want a new XMLreader instance that contains the content of the language node ONLY. Not sure how to do this though. I know how to read strings etc... just not sure how to read the contents of the language node. I have tried what is above. I have tried InnerXML and OuterXML. Both of these return "None" as my XML. My comments point to where my knowledge falls short.
The XmlReader is pretty low level, and I would not recommend you use it. Better options: - Use XDocument[^]. The examples on the page are focusing on creating the document, but use the static Load or Create methods when you already have the file. - Make a full C# class representing your XML and use the DataContract serializer - then get your data from there using standard C# code. XmlReader is very good at dealing with XML where you do not want to keep everything in memory - if that is a requirement, then you might have made a mistake somewhere earlier in the project. That said, the XmlNodeReader[^] is doing what you are asking for.
-
The XmlReader is pretty low level, and I would not recommend you use it. Better options: - Use XDocument[^]. The examples on the page are focusing on creating the document, but use the static Load or Create methods when you already have the file. - Make a full C# class representing your XML and use the DataContract serializer - then get your data from there using standard C# code. XmlReader is very good at dealing with XML where you do not want to keep everything in memory - if that is a requirement, then you might have made a mistake somewhere earlier in the project. That said, the XmlNodeReader[^] is doing what you are asking for.
Thanks, I used a mix of XmlReader and XmlDocument to resolve it so it is similar to your suggestion.