How to declare a variable with a variable name? - c#

How can I declare a variable inside a for loop
foreach (System.Xml.XmlNode xmlnode in node)
{
string AMSListName = xmlnode.Attributes["Title"].Value.ToString();
/* the below assignment should be variable for each iteration */
XmlNode ndViewFields + AMSListName = xmlDoc.CreateNode(XmlNodeType.Element,
"ViewFields", "");
}
How do I achieve this? I want for each value in the for loop to have the xmlnode to have a different name. Is this possible at all?

Use a collection:
List<XmlNode> nodes = new List<XmlNode>();
foreach (System.Xml.XmlNode xmlnode in node)
{
string AMSListName = xmlnode.Attributes["Title"].Value.ToString();
nodes.Add(xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", ""));
}
You can access this list via index or in a loop:
foreach(var node in nodes)
{
// ...
}
another approach If the name is an identifier, use a Dictionary:
Dictionary<string, System.Xml.XmlNode> nodeNames = new Dictionary<string, System.Xml.XmlNode>();
foreach (System.Xml.XmlNode xmlnode in node)
{
string AMSListName = xmlnode.Attributes["Title"].Value.ToString();
nodeNames[AMSListName] = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");
}
This will replace an already available node with a given name, otherwise it'll add it.
You can access it via name:
XmlNode node
if(nodeNames.TryGetValue("Some Name", out node)
{
// ..
};

I would suggest using something like a dictionary or hastable. Because even if you did create dynamic variables, how would you reference them later? I am not sure this is possible.
Hashtable ViewFields = new Hashtable();
foreach (System.Xml.XmlNode xmlnode in node)
{
string AMSListName = xmlnode.Attributes["Title"].Value.ToString();
XmlNode nd = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");
ViewFields.Add(AMSListName,nd);
}

Related

How to check if an XML node exists in the children of another node?

I want to add an XmlNode to another XmlNode if it doesn't contain this node (the comparison should be based on the node name and its contents)
System.Xml.XmlDocument doc;
...
XmlNode newNode = doc.CreateElement(name);
newNode.InnerXml = something
XmlNode parentNode = doc.GetElementsByTagName(parentName);
if (parentNode.???? (newNode))
{
parentNode.AppendChild(newNode);
}
How can I check this existence? parentNode.ChildNodes doesn't have a Contain method.
I think this will do the trick:
private void doSomething()
{
XmlDocument doc = new XmlDocument();
XmlNode newNode = doc.CreateElement("name");
newNode.InnerXml = "something";
XmlNode parentNode = doc.GetElementsByTagName("parentName")[0];
// I just stuck an index on end of above line...
// Note that GetElementsByTagName returns an XmlNodeList
int huh = 0;
foreach (XmlNode n in parentNode.ChildNodes)
{
// If I understood you correctly, you want these checks?
if (n.InnerXml == newNode.InnerXml && n.Name == newNode.Name) huh++;
}
if (huh == 0) parentNode.AppendChild(newNode);
}
You could do this using LINQ to XML making use of the XNode.DeepEquals method to compare your child nodes for equality. An example might look like this - the duplicateChild will not be added but newChild will be:
var doc = new XDocument(
new XElement("parent",
new XElement("child", 1)));
var parent = doc.Descendants("parent").Single();
var duplicateChild = new XElement("child", 1);
var newChild = new XElement("child", 2);
if (!parent.Elements().Any(e => XNode.DeepEquals(e, duplicateChild)))
{
parent.Add(duplicateChild);
}
if (!parent.Elements().Any(e => XNode.DeepEquals(e, newChild)))
{
parent.Add(newChild);
}
A demo here: https://dotnetfiddle.net/1t4Q1b

How to get xml element values using XmlNodeList in c#

I need to store the element values which are inside the nodes "member" . I have tried the following code but I can't achieve it. How to get the values. Any help would be appreciated
XML:
<ListInventorySupplyResponse xmlns="http://mws.amazonaws.com/FulfillmentInventory/2010-10-01/">
<ListInventorySupplyResult>
<InventorySupplyList>
<member>
<SellerSKU>043859634910</SellerSKU>
<FNSKU>X000IA4045</FNSKU>
<ASIN>B005YV4DJO</ASIN>
<Condition>NewItem</Condition>
<TotalSupplyQuantity>7</TotalSupplyQuantity>
<InStockSupplyQuantity>7</InStockSupplyQuantity>
<EarliestAvailability>
<TimepointType>Immediately</TimepointType>
</EarliestAvailability>
<SupplyDetail>
</SupplyDetail>
</member>
</InventorySupplyList>
</ListInventorySupplyResult>
<ResponseMetadata>
<RequestId>58c9f4f4-6f60-496a-8d71-8fe99ce301c9</RequestId>
</ResponseMetadata>
</ListInventorySupplyResponse>
C# Code:
string a = Convert.ToString(oInventorySupplyRes.ToXML());
XmlDocument oXdoc = new XmlDocument();
oXdoc.LoadXml(a);
XmlNodeList oInventorySupplyListxml = oXdoc.SelectNodes("//member");
foreach (XmlNode itmXml in oInventorySupplyListxml)
{
// var cond = itmXml.InnerXml.ToString();
var asinVal = itmXml.SelectSingleNode("ASIN").Value;
var TotalSupplyQuantityVal = itmXml.SelectSingleNode("TotalSupplyQuantity").Value;
}
ResultView : "Enumeration yielded no results" and count = 0;
Edit 1:
string a = Convert.ToString(oInventorySupplyRes.ToXML());
var status = oInventorySupplyResult.InventorySupplyList;
XmlDocument oXdoc = new XmlDocument();
var doc = XDocument.Parse(a);
var r = doc.Descendants("member")
.Select(member => new
{
ASIN = member.Element("ASIN").Value,
TotalSupplyQuantity = member.Element("TotalSupplyQuantity").Value
});
private string mStrXMLStk = Application.StartupPath + "\\Path.xml";
private System.Xml.XmlDocument mXDoc = new XmlDocument();
mXDoc.Load(mStrXMLStk);
XmlNode XNode = mXDoc.SelectSingleNode("/ListInventorySupplyResult/InventorySupplyList/member");
if (XNode != null)
{
int IntChildCount = XNode.ChildNodes.Count;
for (int IntI = 1; IntI <= IntChildCount ; IntI++)
{
string LocalName = XNode.ChildNodes[IntI].LocalName;
XmlNode Node = mXDoc.SelectSingleNode("/Response/" + LocalName);
// Store Value in Array assign value by "Node.InnerText"
}
}
Try This Code. Its Worked
try using this xpath
string xPath ="ListInventorySupplyResponse/ListInventorySupplyResult
/InventorySupplyList/member"
XmlNodeList oInventorySupplyListxml = oXdoc.SelectNodes(xpath);
when you do "//member", then, the code is trying to look for element named member from the root level, which is not present at the root level, rather it is nested beneath few layers.
I think this will help you..
string a = Convert.ToString(oInventorySupplyRes.ToXML());
XmlDocument oXdoc = new XmlDocument();
oXdoc.LoadXml(a);
XmlNodeList fromselectors;
XmlNodeList toselectors;
XmlElement root = oXdoc.DocumentElement;
fromselectors = root.SelectNodes("ListInventorySupplyResult/InventorySupplyList/member/ASIN");
toselectors = root.SelectNodes("ListInventorySupplyResult/InventorySupplyList/member/TotalSupplyQuantity");
foreach (XmlNode m in fromselectors)
{
you will have value in `m.InnerXml` use it whereever you want..
}
foreach (XmlNode n in toselectors)
{
you will have value in `n.InnerXml` use it whereever you want..
}

Renaming xmlnodes using c# dynamically

I am using the below code to rename the xmlnode name dynamically. It's looping though the xml just fine, but it does not change the node name. Please help me to do this.
Sample XML doucment
- <NewDataSet>
- <Table5>
<FLD_ID>62</FLD_ID>
<FLD_DATE>2013-03-12</FLD_DATE>
<FLD_MOD_DATE>2013-04-05</FLD_MOD_DATE>
<FLD_DESC>New Creation</FLD_DESC>
</Table5>
- </NewDataSet>
Needed XML DOCUMENT
- <rows>
- <row>
<cell>62</cell>
<cell>2013-03-12</cell>
<cell>2013-04-05</cell>
<cell>New Creation</cell>
</row>
- </rows>
My code is here
XmlNode PackageListNode = hst_doc.SelectSingleNode("NewDataSet");
XmlNodeList PackageNodeList = PackageListNode.SelectNodes("Table5");
foreach (XmlNode node in PackageNodeList)
{
node.Name.Replace("Table5", "row");
foreach (XmlNode ls in node)
{
ls.Name.Replace(ls.Name, "cell");
}
}
As you can't replace element names in an XmlDocument...
...a replacement approach for your specific situation:
string srcXML = "<NewDataSet><Table5><FLD_ID>62</FLD_ID><FLD_DATE>2013-03-12</FLD_DATE><FLD_MOD_DATE>2013-04-05</FLD_MOD_DATE><FLD_DESC>New Creation</FLD_DESC></Table5></NewDataSet>";
var doc = new XmlDocument();
doc.LoadXml(srcXML);
XmlNode oldRoot = doc.SelectSingleNode("NewDataSet");
XmlNode newRoot = doc.CreateElement("rows");
doc.ReplaceChild(newRoot, oldRoot);
foreach (XmlNode childNode in oldRoot.ChildNodes)
{
newRoot.AppendChild(childNode.CloneNode(true));
}
XmlNodeList PackageNodeList = newRoot.SelectNodes("Table5");
foreach (XmlNode node in PackageNodeList)
{
var newNode = doc.CreateElement("row");
newRoot.ReplaceChild(newNode, node);
foreach (XmlNode childNode in node.ChildNodes)
{
var clonedChildNode = childNode.CloneNode(true);
newNode.AppendChild(clonedChildNode);
var newChildNode = doc.CreateElement("cell");
newNode.ReplaceChild(newChildNode, clonedChildNode);
foreach (XmlNode childChildNode in clonedChildNode.ChildNodes)
{
newChildNode.AppendChild(childChildNode.CloneNode(true));
}
}
}
Debug.Print(doc.OuterXml);
Embrace LINQ, embrace it!
// load the document from a file
var doc = XDocument.Load(xmlPath);
var root = doc.Root;
// replace the root element with a new element
root.ReplaceWith(
// create a new element with
// the name "rows" with new children
new XElement("rows",
// replace all child elements of
// the root with new elements
root.Elements().Select(table =>
// replace the current element with a new element
// with the name "row" with the new children
new XElement("row",
// replace all child elements of the
// current element with new elements
table.Elements().Select(field =>
// replace the current element with a new element
// with the name "cell" with the same value
new XElement("cell",
(string)field
)
)
)
)
)
);
// save the document back to the file
doc.Save(xmlPath);
String.Replace returns a new string, so of course one would love to:
node.Name = node.Name.Replace("Table5", "row");
which might as well be
node.Name = "row";
however, if you look at the documentation it says that XmlNode.Name is purely a 'getter' and not a 'setter', so maybe you'll need to create whole new nodes to replace them, it depends on the actual implementation, since XmlNode is an abstract class.
for (int i = 0; i < PackageNodeList.Count; ++i) XmlNode node in PackageNodeList)
{
XmlNode replacementNode = new XmlNode("row");
foreach (XmlNode ls in node)
{
XmlNode newCell = new XmlNode("cell");
newCell.Value = ls.Value;
replacementNode.AppendChild(newCell);
}
PackageNodeList[i] = replacementNode
PackageNodeList[i].ParentNode.ReplaceChild(PackageNodeList[i], replacementNode);
}

How to add nodes with the same name in a loop?

I'm trying to create the following XML file:
<Clientes>
<Cliente>
<Name>sfsdfsd</Name>
<Phone>
</Phone>
<Matriculas>
<Matricula>
<Nr>567856786</Nr>
<Marca>86786</Marca>
<Modelo>8678678</Modelo>
</Matricula>
<Matricula>
<Nr>u56u5u</Nr>
<Marca>4564b5</Marca>
<Modelo>b456b</Modelo>
</Matricula>
</Matriculas>
</Cliente>
</Clientes>
I have several clientes stored in a List and each of them may have more then one Matricula, stored in a List
i have the following code:
foreach (Cliente c in cli)
{
XmlNode xCliente = xDoc.CreateElement("Cliente");
XmlNode xName = xDoc.CreateElement("Name");
XmlNode xPhone = xDoc.CreateElement("Phone");
XmlNode xMatriculas = xDoc.CreateElement("Matriculas");
XmlNode xMatricula = xDoc.CreateElement("Matricula");
XmlNode xNr = xDoc.CreateElement("Nr");
XmlNode xMarca = xDoc.CreateElement("Marca");
XmlNode xModelo = xDoc.CreateElement("Modelo");
xName.InnerText = c.Name;
xPhone.InnerText = c.Phone;
xCliente.AppendChild(xName);
xCliente.AppendChild(xPhone);
foreach (Matricula m in c.matricula)
{
xNr.InnerText = m.nr;
xMarca.InnerText = m.marca;
xModelo.InnerText = m.modelo;
xMatricula.AppendChild(xNr);
xMatricula.AppendChild(xMarca);
xMatricula.AppendChild(xModelo);
xMatriculas.AppendChild(xMatricula);
}
xCliente.AppendChild(xMatriculas);
xDoc.DocumentElement.AppendChild(xCliente);
}
i can add several Cliente to the root, but only the last Matricula in Matriculas is added.
Move
XmlNode xMatricula = xDoc.CreateElement("Matricula");
XmlNode xNr = xDoc.CreateElement("Nr");
XmlNode xMarca = xDoc.CreateElement("Marca");
XmlNode xModelo = xDoc.CreateElement("Modelo");
inside the inner for loop.
You are reusing the exact same node, you need to create a new node every time you want a new node in your document.

Xml node reading for each loop

I am trying to loop through an Xml file and display the value for account in a message.
XmlNodeList nodeList = testDoc.SelectNodes("/details/row/var");
foreach (XmlNode no in nodeList)
{
XmlNode node = testDoc.SelectSingleNode("/details/row/var[#name='account']");
test.actual = node.Attributes["value"].Value;
MessageBox.Show(test.account);
}
The message box is currently displaying the first record repeatidly, how can I get to the next record?
Thanks for your input in advance.
You are repeatedly assigning node with the same element from testDoc. It is not clear what test.account is (perhaps a mistype for test.actual)?
no is the variable which will iterate the contents of nodeList - I imagine you intended to use that.
EDIT following edit of OP
Now you've shown us what nodeList is, I suspect you want to do something like this instead :
XmlNodeList nodeList = testDoc.SelectNodes("/details/row/var[#name='account']");
foreach (XmlNode no in nodeList)
{
test.actual = no.Attributes["value"].Value;
...
XmlDocument doc = new XmlDocument();
doc.Load("d:\\test.xml");
XmlNodeList node = doc.GetElementsByTagName("w:r");
foreach (XmlNode xn in node)
{
try
{
if (xn["w:t"].InnerText != null)
{
if (xn["w:t"].InnerText == "#")
{
string placeHolder = xn["w:t"].InnerText;
foreach (XmlNode a in node)
{
if (a["w:t"].InnerText != "#")
{
string placeHolder1 = a["w:t"].InnerText;
}
}
}
}
}
catch (Exception e)
{
Console.Write(e);
}
}
Here is the sample for parent node value to get information of the child nodes.here i am using the ReportItems ParentNode and Print only image child nodes.
xmldoc.Load(rdlFile);
StringBuilder sb=new StringBuilder();
XmlNode node = xmldoc.GetElementsByTagName("ReportItems")[0];
XmlNodeList list = node.ChildNodes;
atributes=new string[node.ChildNodes.Count];
int l = 0;
for (int j = 0; j < node.ChildNodes.Count; j++)
{
if (list[j].Name == "Image")
{
XmlAttributeCollection att = list[j].Attributes;
atributes[l] = att[0].Value.ToUpper();
}
l++;
}
for (int i = 0; i < node.ChildNodes.Count; i++)
{
if (searchText.Text.ToUpper() == atributes[i])
{
XmlNodeList lastlist = node.ChildNodes;
XmlNodeList endlist = lastlist[i].ChildNodes;
for (int k = 0; k < endlist.Count; k++)
{
sb.Append(endlist[k].Name+" - "+ endlist[k].InnerText);
sb.Append("\n"+"\n");
}
}
}
let me know if you have doubt..
Try this,
XmlDocument xdoc = new XDocument();
xdoc.Load("*/File/*");
string xmlcontents = xdoc.InnerXml;
var xpath = "(/details/row/var[#name='account'])";
XmlNodeList lists = xdoc.DocumentElement.SelectNodes(xpath);
foreach (XmlNode _node in lists)
{
string _nodeValue = _node.InnerText;
MessageBox.Show(_nodeValue);
}
Try the following:
//Create an xml reader;
XmlDocument _xmlDocument = new XmlDocument();
_xmlDocument.Load(/*File Name here*/);
//Select the element with in the xml you wish to extract;
XmlNodeList _nodeList = _xmlDocument.SelectNodes("/details/row/var[#name='account']");
//Display the values in the node list to the screen;
foreach (XmlNode _node in _nodeList)
{
String _nodeValue = _node.InnerText.ToString();
MessageBox.Show(_nodeValue.ToString());
}
I'm not 100% sure, but you may need to use recursion. If not, it should just look like this:
XmlDocument doc = //etc..
foreach(XmlNode node in doc.ChildNodes)
{
if(node.Name == "account")
{
MessageBox.Show(node.Value);
}
}
You shouldn't spend time with reading the xml node by node. Try Deserialization:

Categories

Resources