removing namespace from xml - c#

I have an xml as shown:
<?xml version="1.0" encoding="utf-8"?>
<Query_advanced>
<Query>hy</Query>
<Attribute Name1="Patient's Age" Value1="23" xmlns="xyz"/>
<Attribute Name1="Patient's Birth Date" Value1="24/12/1988" xmlns="xyz"/>
<Attribute Name1="Patient's Name" Value1="xyz" xmlns="xyz" />
</Query_advanced>
I need to read through the xml to get the values of Name1 and of Value1, but im unable to do so with the xmlns there. Is there any way i could do so? Ive tried using:
XmlNamespaceManager xnm = new XmlNamespaceManager(xdoc.NameTable);
xnm.RemoveNamespace("Attribute", "xyz");

I think you've not to remove the namespace, but you've to add it to the XmlNameSpaceManager, in order to use a prefix (as #John Saunders comments), for example, in a XPath expression.
Try this:
XmlNamespaceManager xnm = new XmlNamespaceManager(xdoc.NameTable);
xnm.AddNamespace("a", "xyz");
// Cycle through the Attribute nodes
foreach (XmlNode node in xdoc.SelectNodes("//Query_advanced/a:Attribute", xnm))
{
// And read the attributes of the node
string NameAttribute = node.Attributes["Name1"].Value;
string ValueAttribute = node.Attributes["Value1"].Value;
}

Use XmlReader or XmlTextReader if you have a file.
Here an example:
http://msdn.microsoft.com/en-us/library/cc189056(v=vs.95).aspx
In your example Attribute is a xml tag, not a namespace. Name1 and Value1 are xml attributes of the tag Attribute.
So you need to read the attributes of the tag Attribute.
Let xmlString is the xml you want to parse:
using (XmlReader reader = XmlReader.Create(new StringReader(xmlString)))
{
while(reader.ReadToFollowing("Attribute")){ //loop read Attribute tag
reader.MoveToFirstAttribute();
string Name1 = reader.Value; //do something with Name1
reader.MoveToNextAttribute();
string Value1 = reader.Value; //do something with Value1
}
}

THanks for all your suggestions! I managed to do it this way:
private void QueryXML()
{
XmlDocument query_xml = new XmlDocument();
query_xml.Load("Query_1.xml");
XmlNodeList elements = query_xml.GetElementsByTagName("Attribute");
string[] s = new string[elements.Count];
for (int i = 0; i < elements.Count; i++)
{
string attrVal = elements[i].Attributes["Value1"].Value;
Console.Writeline(attrval)
}
Thanks a bunch! :)

Related

C# - Can I select the value of an XML attribute by searching for a second attribute?

I want to select the value of the "data" attribute where the "key" attribute matches a specific search.
The XML file will look like this.
<connections>
<production>
<connection key="KEY1" data="value1" />
<connection key="KEY2" data="value2" />
<connection key="KEY3" data="value3" />
</production>
</connections>
So is there a way to return the value of the data attribute by searching for key = key1 for example?
You could do something like this if you wanted to avoid using XPath.
using System.Xml.Linq;
var xmlStr = File.ReadAllText("Testfile.xml");
XElement root = XElement.Parse(xmlStr);
var data = root.Element("production")
.Elements().Where(x => x.Attribute("key").Value == "KEY1")
.Select(x=>x.Attribute("data").Value)
.First();
Console.WriteLine(data);
Try this, using System.Xml you can read the xml file in question and iterate through the nodes to look for your value.
private void YOUR_METHOD_NAME()
{
// Call GetXml method which returns the result in the form of string
string result = GetXml("xmlfile.xml", "KEY2");
Debug.WriteLine(result);
}
private string GetXml(string filePath, string searchKey)
{
XmlDocument doc = new XmlDocument();
doc.Load(filePath);
XmlNodeList nodes = doc.SelectSingleNode("//connections/production").ChildNodes;
string output = string.Empty;
foreach (XmlNode node in nodes)
{
if (node.Attributes["key"].Value == searchKey)
{
output = node.Attributes["data"].Value;
}
else
{
continue;
}
}
return output;
}

c# Read and store XML nodes to string type reference

I have the below XML:
I need to read only the "ShortName" nodes, but to different string type reference.
How can I refer to source and get shortname's text and then do the same with target?
The xml contains more elements like Valid what I can read one by one with a code like this:
valid = TMElement.GetElementsByTagName("Valid")[0].InnerText;
<GlobalInfo>
<LanguagePair>
<Source>
<ShortName>some data</ShortName>
</Source>
<Target>
<ShortName>some data</ShortName>
</Target>
</LanguagePair>
<Valid>true</Valid>
You can try this:
string xml = #"<GlobalInfo>
<LanguagePair>
<Source>
<ShortName>some data source</ShortName>
</Source>
<Target>
<ShortName>some data target</ShortName>
</Target>
</LanguagePair>
<Valid>true</Valid>
</GlobalInfo>";
XDocument xmlDoc = XDocument.Parse(xml);
LINQ query syntax:
string[] someDataSource =
(from data in xmlDoc.Descendants("Source")
select data.Element("ShortName").Value).ToArray();
string[] someDataTarget = (from data in xmlDoc.Descendants("Target")
select data.Element("ShortName").Value).ToArray();
or method syntax:
string[] someDataSource2 = xmlDoc.Descendants("Source").Select(x => x.Element("ShortName").Value).ToArray();
string[] someDataTarget2 = xmlDoc.Descendants("Target").Select(x => x.Element("ShortName").Value).ToArray();
Try this. Import using System.Xml;
XmlDocument xdoc = new XmlDocument();
// if xml coming via string
string myXml = "<GlobalInfo><LanguagePair><Source><ShortName>some data</ShortName></Source><Target><ShortName>some data</ShortName></Target></LanguagePair></GlobalInfo>";
xdoc.LoadXml(myXml);
string xpath = "GlobalInfo/LanguagePair";//specify path
var nodes = xdoc.SelectNodes(xpath);
foreach (XmlNode childrenNode in nodes)
{
for (int i = 0; i < childrenNode.ChildNodes.Count; i++) {
HttpContext.Current.Response.Write(childrenNode.ChildNodes[i].InnerText);
}
}
Thanks, everybody.
It seems this was easier than I though. Finally, I found my own solution.
Just for the records, I will post it here:
string source = TMElement.SelectSingleNode("LanguagePair/Source/ShortName").InnerText;
string target = TMElement.SelectSingleNode("LanguagePair/Target/ShortName").InnerText;

How do I read xml in C#? [duplicate]

How can I read an XML attribute using C#'s XmlDocument?
I have an XML file which looks somewhat like this:
<?xml version="1.0" encoding="utf-8" ?>
<MyConfiguration xmlns="http://tempuri.org/myOwnSchema.xsd" SuperNumber="1" SuperString="whipcream">
<Other stuff />
</MyConfiguration>
How would I read the XML attributes SuperNumber and SuperString?
Currently I'm using XmlDocument, and I get the values in between using XmlDocument's GetElementsByTagName() and that works really well. I just can't figure out how to get the attributes?
XmlNodeList elemList = doc.GetElementsByTagName(...);
for (int i = 0; i < elemList.Count; i++)
{
string attrVal = elemList[i].Attributes["SuperString"].Value;
}
You should look into XPath. Once you start using it, you'll find its a lot more efficient and easier to code than iterating through lists. It also lets you directly get the things you want.
Then the code would be something similar to
string attrVal = doc.SelectSingleNode("/MyConfiguration/#SuperNumber").Value;
Note that XPath 3.0 became a W3C Recommendation on April 8, 2014.
You can migrate to XDocument instead of XmlDocument and then use Linq if you prefer that syntax. Something like:
var q = (from myConfig in xDoc.Elements("MyConfiguration")
select myConfig.Attribute("SuperString").Value)
.First();
I have an Xml File books.xml
<ParameterDBConfig>
<ID Definition="1" />
</ParameterDBConfig>
Program:
XmlDocument doc = new XmlDocument();
doc.Load("D:/siva/books.xml");
XmlNodeList elemList = doc.GetElementsByTagName("ID");
for (int i = 0; i < elemList.Count; i++)
{
string attrVal = elemList[i].Attributes["Definition"].Value;
}
Now, attrVal has the value of ID.
XmlDocument.Attributes perhaps? (Which has a method GetNamedItem that will presumably do what you want, although I've always just iterated the attribute collection)
Assuming your example document is in the string variable doc
> XDocument.Parse(doc).Root.Attribute("SuperNumber")
1
If your XML contains namespaces, then you can do the following in order to obtain the value of an attribute:
var xmlDoc = new XmlDocument();
// content is your XML as string
xmlDoc.LoadXml(content);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
// make sure the namespace identifier, URN in this case, matches what you have in your XML
nsmgr.AddNamespace("ns", "urn:oasis:names:tc:SAML:2.0:protocol");
// get the value of Destination attribute from within the Response node with a prefix who's identifier is "urn:oasis:names:tc:SAML:2.0:protocol" using XPath
var str = xmlDoc.SelectSingleNode("/ns:Response/#Destination", nsmgr);
if (str != null)
{
Console.WriteLine(str.Value);
}
More on XML namespaces here and here.

XMLReader reading XML file based on attribute value

I am trying to read the following file, I can read the attributes, but I can't go into the specific element (Address in this case) and read its elements based on the attribute of that (Address) element. Shortly I need to distinguish between work and home addresses. I need to do this with XMLReader class. Can you help?
<Address Label="Work">
<Name>Name1</Name>
<Street>PO 1</Street>
<City>City1</City>
<State>State 1</State>
</Address>
<Address Label="Home">
<Name>Name2</Name>
<Street>PO 2</Street>
<City>City2</City>
<State>State 2</State>
</Address>"
Okay, here are some notes to think about. XMLReader in the sense i understand you use it (with no code example) is that you iterate over the document, since the XMLReader is forward-only, and read-only.
Because of this you need to iterate until you find the node you need. In the example below i find the address element labeled "work" and extract that entire node. Then query on this node as you want.
using (var inFile = new FileStream(path, FileMode.Open))
{
using (var reader = new XmlTextReader(inFile))
{
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element:
if (reader.Name == "Address" && reader.GetAttribute(0) == "Work")
{
// Create a document, which will contain the address element as the root
var doc = new XmlDocument();
// Create a reader, which only will read the substree <Address> ... until ... </Address>
doc.Load(reader.ReadSubtree());
// Use XPath to query the nodes, here the "Name" node
var name = doc.SelectSingleNode("//Address/Name");
// Print node name and the inner text of the node
Console.WriteLine("Node: {0}, Inner text: {1}", name.Name, name.InnerText);
}
break;
}
}
}
}
Edit
Made an example that not uses LINQ
XML:
<Countries>
<Country name ="ANDORRA">
<state>Andorra (general)</state>
<state>Andorra</state>
</Country>
<Country name ="United Arab Emirates">
<state>Abu Z¸aby</state>
<state>Umm al Qaywayn</state>
</Country>
Java:
public void datass(string file)
{
string file = HttpContext.Current.Server.MapPath("~/App_Data/CS.xml");
XmlDocument doc = new XmlDocument();
if (System.IO.File.Exists(file))
{
//Load the XML File
doc.Load(file);
}
//Get the root element
XmlElement root = doc.DocumentElement;
XmlNodeList subroot = root.SelectNodes("Country");
for (int i = 0; i < subroot.Count; i++)
{
XmlNode elem = subroot.Item(i);
string attrVal = elem.Attributes["name"].Value;
Response.Write(attrVal);
XmlNodeList sub = elem.SelectNodes("state");
for (int j = 0; j < sub.Count; j++)
{
XmlNode elem1 = sub.Item(j);
Response.Write(elem1.InnerText);
}
}
}
Using XPath you can easily write concise expressions to navigate an XML document.
You would do something like
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(myXMLString);
XmlNode homeAddress = xDoc.SelectSingleNode("//Address[#Label='Work']");
Then do whatever you want with homeAddress.
Read more here on w3schools on XPath.

How to write CData in xml

i have an xml like :
<?xml version="1.0" encoding="UTF-8"?>
<entry>
<entry_id></entry_id>
<entry_status></entry_status>
</entry>
i am writing data in it like:
XmlNode xnode = xdoc.SelectSingleNode("entry/entry_status");
xnode.InnerText = "<![CDATA[ " + Convert.ToString(sqlReader["story_status"]) + " ]]>" ;
but its change "<" to "&lt" of CDATA.
Please tell me how to fill values in above xml as a CData format.
i know that we can create CDATA like :
XmlNode itemDescription = doc.CreateElement("description");
XmlCDataSection cdata = doc.CreateCDataSection("<P>hello world</P>");
itemDescription.AppendChild(cdata);
item.AppendChild(itemDescription);
but my process is to read node of xml and change its value not to append in it.
Thanks
As described here: msdn
// Create an XmlCDataSection from your document
var cdata = xdoc.CreateCDataSection(Convert.ToString(sqlReader["story_status"]));
// Append the cdata section to your node
xnode.AppendChild(cdata);
Do you really need it to be in CDATA, or do you just want to get the text in there in a way which won't require extra escaping in your code?
InnerText performs whatever escaping is required, so generally I'd just use
xnode.InnerText = Convert.ToString(sqlReader["story_status"]);
... but if you really want a CDATA node, you can create one yourself as per Nekresh's answer.
If you really need a CDATA section (see Jon's answer), you can achieve that like so:
XmlNode xnode = xdoc.SelectSingleNode("entry/entry_status");
XmlCDataSection cdata = xdoc.CreateCDataSection(Convert.ToString(sqlReader["story_status"]));
xnode.InnerXml = cdata.OuterXml;
This will replace the contents of xnode, not append to it.
Use Node.InnerXml, not Node.InnerText. Node.InnerText is automatically replacing special values. Note that if you specify with CDATA in InnerXml, then Node.InnerText is text in CDATA.
Example:
public class Test
{
public static int Main(string[] args)
{
const string xmlTxt = #"<?xml version=""1.0"" encoding=""UTF-8""?>
<entry>
<entry_id></entry_id>
<entry_status></entry_status>
</entry>";
TextReader treader = new StringReader(xmlTxt);
XmlReader xreader = XmlReader.Create(treader);
XmlDocument xdoc = new XmlDocument();
xdoc.Load(xreader);
XmlNode xnode = xdoc.SelectSingleNode("entry/entry_status");
//xnode.InnerText = "<![CDATA[something]]>";
xnode.InnerXml = "<![CDATA[something]]>";
Console.WriteLine("inner text is: " + xnode.InnerText);
xdoc.Save(Console.Out); Console.WriteLine();
return 0;
}
}
Program's output:
inner text is: something
<?xml version="1.0" encoding="ibm852"?>
<entry>
<entry_id>
</entry_id>
<entry_status><![CDATA[something]]></entry_status>
</entry>
XmlNode childNode = node.ChildNodes[0];
if (childNode is XmlCDataSection)
{
XmlCDataSection cdataSection = childNode as XmlCDataSection;
cdataSection.Value = newValue;
}
You can use writer.WriteCData(value);
where writer is XmlWriter object.

Categories