I am working on this since yesterday. I have an XML file which looks something like this
<catalog>
<captureInfo>
<row>5</row>
<col>5</col>
</captureInfo>
<patientInfo>
<name>XYZ</name>
<detail>details here</detail>
</patientInfo>
<imageData>
<r0c0>
<contrastFlag>true</contrastFlag>
</r0c0>
<r0c1>
<contrastFlag>true</contrastFlag>
</r0c1>
</imageData>
</catalog>
I need to update the value of contrastFlag in the XML file. This is the code I have written:
XmlDocument doc = new XmlDocument();
XmlNodeList imageData = doc.GetElementsByTagName("imageData");
foreach(XmlNode node in imageData)
{
foreach (XmlNode innernode in node)
{
if (innernode.Name == "r0c0")
{
innernode.InnerText = "false";
}
}
}
doc.Save("XMLFile1.xml");
Can anyone tell me where am I going wrong and also is there any better/faster approach for this?
Well first off, your XML is malformed, the closing should match "catalog". Why not just do this:
string xml = #"<catalog>
<captureInfo>
<row>5</row>
<col>5</col>
</captureInfo>
<patientInfo>
<name>XYZ</name>
<detail>details here</detail>
</patientInfo>
<imageData>
<r0c0>
<contrastFlag>true</contrastFlag>
</r0c0>
<r0c1>
<contrastFlag>true</contrastFlag>
</r0c1>
</imageData>
</catalog>";
XmlDocument xdoc = new XmlDocument();
xdoc.LoadXml(xml);
xdoc.SelectSingleNode("//catalog/imageData/r0c0/contrastFlag").InnerText = "false";
Here is a way to replace all of the instances using LINQ. I just wrote out to a new file to preserve the source.
StreamReader stream = new StreamReader(#"c:\test.xml");
XDocument doc = XDocument.Load(stream);
IEnumerable<XElement> flags = doc.Descendants("contrastFlag");
foreach (XElement e in flags)
{
e.Value = "false";
}
doc.Save(#"c:\test2.xml");
Related
I have xml file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><SENT_110 xmlns:ns2="http://www.mf.gov.pl/SENT/2017/01/18/STypes.xsd" xmlns="http://www.mf.gov.pl/SENT/2017/01/18/SENT_110.xsd"><SentNumber>SENT20180416000032</SentNumber><KeyNumber><ns2:SenderKey>KS-28YM</ns2:SenderKey><ns2:RecipientKey>KR-52DH</ns2:RecipientKey><ns2:CarrierKey>KD-48WW</ns2:CarrierKey></KeyNumber>
I want to read in separate SenderKey, RecipientKey & CarrierKey.
When i use this code:
XmlTextReader reader = new XmlTextReader(file);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ns", xmlDoc.DocumentElement.NamespaceURI);
XmlNodeList nodeList = xmlDoc.SelectNodes("/ns:SENT_110/ns:KeyNumber", nsmgr);
foreach (XmlNode node in nodeList)
{
key = node.InnerText;
MessageBox.Show(key);
}
i've got something like this: KS-28YMKR-52DHKD-48WW, without any separate between key.
How i could read only one key?
Use the following XPath:
"/ns:SENT_110/ns:KeyNumber/*"
It will return all nested nodes to you.
If the structure of the XML is fixed it is rather easy by using XDocument:
var xmlText = "<SENT_110 xmlns:ns2=\"http://www.mf.gov.pl/SENT/2017/01/18/STypes.xsd\" xmlns=\"http://www.mf.gov.pl/SENT/2017/01/18/SENT_110.xsd\"><SentNumber>SENT20180416000032</SentNumber><KeyNumber><ns2:SenderKey>KS-28YM</ns2:SenderKey><ns2:RecipientKey>KR-52DH</ns2:RecipientKey><ns2:CarrierKey>KD-48WW</ns2:CarrierKey></KeyNumber></SENT_110>";
var xml = XDocument.Parse(xmlText);
var nodes = xml.Descendants();
var senderKey = nodes.First(d => d.Name.ToString().EndsWith("SenderKey")).Value;
var recipientKey = nodes.First(d => d.Name.ToString().EndsWith("RecipientKey")).Value;
var carrierKey = nodes.First(d => d.Name.ToString().EndsWith("CarrierKey")).Value;
See HERE for a working snippet. If this is just a part of a bigger XML or the structure can be different maybe some more complex searching is needed.
Please, Help me Out Here
I Want to display the value of "email" from xml. my syntax works for now but it displays every value. i want to be able to display Individual (one) Values like
email: mail#mail.com
My scripts
var xml ="<?xml version='1.0' encoding='UTF-8'?>
<MemResponse>
<Phone>2554535</Phone>
<Email>mail#mail</Email>
<Number>we75546654</Number>
</MemResponse>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
foreach(XmlNode n in doc.DocumentElement)
{
string q = n.FirstChild.InnerText;
Response.Write(q);
}
Simply you can select all element by tag name by GetElementsByTagName method.
Check this :
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
var myEmails = doc.GetElementsByTagName("Email");
foreach (XmlNode mail in myEmails)
{
string mailText = mail.FirstChild.InnerText;
Response.Write(mailText);
}
I have got it from MSDN
Your code goes through each node and writes the contents of that node.
It seems like you want to match on the node name, and only write the value if its name is "email".
If thats the case, inside of your for each, try something like:
if(n.Name == "Email") {
string q = n.FirstChild.InnerText;
Response.Write(q);
}
Alternatively, you could just use a node list.
NodeList nl = doc.GetElementsByTagName("Email");
And write that.
When loading your XML Doc, use :
HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(response.GetResponseStream());
Please try this code:
XmlDocument doc = new XmlDocument();
doc.LoadXml("YOUR_XML_PATH");
XmlNodeList email_hd= doc.GetElementsByTagName("Email");
string email=email_hd[0].InnerText;
I have the xml below in a c# class.
string xml =#"<?xml version='1.0' encoding='UTF-8'?>
<call method='importCube'>
<credentials login='sampleuser#company.com' password='my_pwd' instanceCode='INSTANCE1'/>
<importDataOptions version='Plan' allowParallel='false' moveBPtr='false'/>
I need to update the XML held within the node attributes i.e.
string xml =#"<?xml version='1.0' encoding='UTF-8'?>
<call method='importCube'>
<credentials login='testuser#test.com' password='userpassword' instanceCode='userinstance'/>
<importDataOptions version='Actual' allowParallel='true' moveBPtr='true'/>
I've written code to do this :
// instantiate XmlDocument and load XML from string
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
// get a list of nodes
XmlNodeList aNodes = doc.SelectNodes("/call/credentials");
// loop through all nodes
foreach (XmlNode aNode in aNodes)
{
// grab the attribute
XmlAttribute idLogin = aNode.Attributes["login"];
XmlAttribute idPass = aNode.Attributes["password"];
XmlAttribute idInstance = aNode.Attributes["instanceCode"];
idLogin.Value = "myemail.com";
idPass.Value = "passtest";
idInstance.Value = "TestInstance";
}
It works but the issue at the minute is that I have to repeat the whole code block for each node path i.e.
XmlNodeList aNodes = doc.SelectNodes("/call/importDataOptions");
....
There has to be a better way. Any ideas how I can rip through the attributes in 1 pass?
Maybe just using a cast to XmlElement could help you to reduce your code:
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
foreach (XmlElement credential in doc.SelectNodes("/call/credentials"))
{
credential.SetAttribute("login" , "myemail.com" );
credential.SetAttribute("password" , "passtest" );
credential.SetAttribute("instanceCode", "TestInstance");
}
Another option is to create an object structure which resembles your XML vocabulary and deserialize your input into that objects, but it seems overkill.
EDIT: Per your comment, you could go with:
foreach (XmlElement node in doc.SelectNodes("/call/*")) // it's case sensitive
{
switch(node.Name)
{
case "credentials":
node.SetAttribute("login" , "myemail.com" );
node.SetAttribute("password" , "passtest" );
node.SetAttribute("instanceCode", "TestInstance");
break;
case "importDataOptions":
// ...
break;
default:
throw new ArgumentOutOfRangeException("Unexpected node: "+node.Name);
}
}
I have this XML file, I can read all the the nodes
<?xml version="1.0" encoding="UTF-8"?>
<cteProc xmlns="http://www.portalfiscal.inf.br/cte" versao="1.04">
<CTe xmlns="http://www.portalfiscal.inf.br/cte">
<infCte versao="1.04" ID="CTe3512110414557000014604"></infCte>
</CTe>
</cteProc>
I have tried reading this using C#
string chavecte;
string CaminhoDoArquivo = #"C:\Separados\13512004-procCTe.xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(CaminhoDoArquivo); //Carregando o arquivo
chavecte = xmlDoc.SelectSingleNode("infCTe")
.Attributes.GetNamedItem("Id").ToString();
but something is wrong with this code.
If you want to use Linq To Xml
var xDoc = XDocument.Load(CaminhoDoArquivo);
XNamespace ns = "http://www.portalfiscal.inf.br/cte";
var chavecte = xDoc.Descendants(ns+"infCte").First().Attribute("id").Value;
PS: I am assuming your xml's invalid line is as
<infCte versao="1.04" id="CTe3512110414557000014604"></infCte>
replace
chavecte = xmlDoc.SelectSingleNode("infCTe").Attributes.GetNamedItem("Id").Value;
with
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ab", "http://www.portalfiscal.inf.br/cte");
chavecte = xmlDoc.SelectSingleNode("//ab:infCte", nsmgr)
.Attributes.GetNamedItem("Id").Value;
I've also noticed that infCte doesn't have the ID attribute properly defined in your xml
Another possible solution is:
string CaminhoDoArquivo = #"C:\Separados\13512004-procCTe.xml";
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(CaminhoDoArquivo); //Carregando o arquivo
// Select the node you're interested in
XmlNode node = xmlDoc.SelectSingleNode("/cteProc/CTe/infCte");
// Read the value of the attribute "ID" of that node
string chavecte = node.Attributes["ID"].Value;
I'm trying to parse XML returned from the Youtue API. The APIcalls work correctly and creates an XmlDocument. I can get an XmlNodeList of the "entry" tags, but I'm not sure how to get the elements inside such as the , , etc...
XmlDocument xmlDoc = youtubeService.GetSearchResults(search.Term, "published", 1, 50);
XmlNodeList listNodes = xmlDoc.GetElementsByTagName("entry");
foreach (XmlNode node in listNodes)
{
//not sure how to get elements in here
}
The XML document schema is shown here: http://code.google.com/apis/youtube/2.0/developers_guide_protocol_understanding_video_feeds.html
I know that node.Attributes is the wrong call, but am not sure what the correct one is?
By the way, if there is a better way (faster, less memory) to do this by serializing it or using linq, I'd be happy to use that instead.
Thanks for any help!
Here some examples reading the XmlDocument. I don't know whats fastest or what needs less memory - but i would prefer Linq To Xml because of its clearness.
XmlDocument xmlDoc = youtubeService.GetSearchResults(search.Term, "published", 1, 50);
XmlNodeList listNodes = xmlDoc.GetElementsByTagName("entry");
foreach (XmlNode node in listNodes)
{
// get child nodes
foreach (XmlNode childNode in node.ChildNodes)
{
}
// get specific child nodes
XPathNavigator navigator = node.CreateNavigator();
XPathNodeIterator iterator = navigator.Select(/* xpath selector according to the elements/attributes you need */);
while (iterator.MoveNext())
{
// f.e. iterator.Current.GetAttribute(), iterator.Current.Name and iterator.Current.Value available here
}
}
and the linq to xml one:
XmlDocument xmlDoc = youtubeService.GetSearchResults(search.Term, "published", 1, 50);
XDocument xDoc = XDocument.Parse(xmlDoc.OuterXml);
var entries = from entry in xDoc.Descendants("entry")
select new
{
Id = entry.Element("id").Value,
Categories = entry.Elements("category").Select(c => c.Value)
};
foreach (var entry in entries)
{
// entry.Id and entry.Categories available here
}
I realise this has been answered and LINQ to XML is what I'd go with but another option would be XPathNavigator. Something like
XPathNavigator xmlNav = xmlDoc.CreateNavigator();
XPathNodeIterator xmlitr = xmlNav.Select("/XPath/expression/here")
while (xmlItr.MoveNext()) ...
The code is off the top of my head so it may be wrong and there may be a better way with XPathNavigator but it should give you the general idea
You could use XSD.exe to generate a class based on the schema provided. Once generated, you could then parse the XML response into the strongly typed class.
string xmlResponse = GetMyYouTubeStuff();
MyYouTubeClass response = null;
XmlHelper<MyYouTubeClass> xmlHelper = new XmlHelper<MyYouTubeClass>();
response = xmlHelper.Deserialize(xmlResponse);
And the class for deserializing it...
public class XmlHelper<T>
{
public T Deserialize(string xml)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
Byte[] byteArray = new UTF8Encoding().GetBytes(xml);
MemoryStream memoryStream = new MemoryStream(byteArray);
XmlTextReader xmlTextReader = new XmlTextReader(memoryStream);
T retObj = (T)xs.Deserialize(xmlTextReader);
return retObj;
}
}
There's also another way here.