How I can get all nodes from XSD in C# like this:
I have this example:
Data I need:
employees/
employees/employee/
employees/employee/name
employees/employee/adress
employees/employee/adress/postalcode/
I need all possible node from XSD. I used XmlSchema element.Attribute but I can get parent nodes, any ideas?
My Code:
var xs = XNamespace.Get("http://www.w3.org/2001/XMLSchema");
var doc = XDocument.Parse(xml);
string node = string.Empty;
foreach (var element in doc.Descendants(xs + "element"))
{
string name = element.Attribute("name").Value+"/";
node += name;
}
Related
I'm complete rookie I need to retrieve the value of last id in XML file here is
You can also use XPath within the Xml DOM like this :
string title;
XmlDocument xml = new XmlDocument();
xml.Load("~/purchases.xml");
// Or any other method to load your xml data in the XmlDocument.
// For example if your xml data are in a string, use the LoadXml method.
XmlElement elt = xml.SelectSingleNode("//SubMenu[#id='1']") as XmlElement;
if(elt!=null)
{
name=elt.GetAttribute("title");
}
Reference
As Jon suggested, you can use Linq To XML here.
XElement books = XElement.Load(filePath);
var lastId = books.Descendants("book").Select(x=>Int32.Parse(x.Attribute("ID").Value)).Last();
This will give you the last ID in the current list.You can now create your new Node
books.Add(new XElement("book",new XAttribute("ID",(lastId+1).ToString()),
new XAttribute("title","New Title"),
new XAttribute("price","1234")));
books.Save(filePath);
XmlDocument doc = new XmlDocument();
doc.Load("Yourxmlfilepath.xml");
//Display all the book titles.
XmlNodeList xNodeList = doc.SelectNodes("/bookstore/book");
foreach (XmlNode xNode in xNodeList)
{
var employeeName = xNode.OuterXml;
XmlDocument docnew = new XmlDocument();
docnew.LoadXml(employeeName);
foreach (XmlElement report in docnew.SelectNodes("book"))
{
string ID = report.GetAttribute("ID");
string title = report.GetAttribute("title");
string quantity = report.GetAttribute("quantity");
string price = report.GetAttribute("price");
}
}
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..
}
I want to update the xml document and i need to return the updated xml in string. I am trying like below. when i save the document it expects the file name. but i dont want to save this as file. i just want to get the updated xml in string.
string OldXml = #"<Root>
<Childs>
<first>this is first</first>
<second>this is second </second>
</Childs
</Root>";
XmlDocument NewXml = new XmlDocument();
NewXml.LoadXml(OldXml );
XmlNode root = NewXml.DocumentElement;
XmlNodeList allnodes = root.SelectNodes("*");
foreach (XmlNode eachnode in allnodes)
{
if (eachnode.Name == "first")
{
eachnode.InnerText = "1";
}
}
NewXml.Save();
string newxml = NewXml.OuterXml;
You don't need to call Save method because string is immutable, your problem is in root.SelectNodes("*"), it just get child nodes, not all level of nodes. You need to go one more level:
foreach (XmlNode eachnode in allnodes)
{
var firstNode = eachnode.ChildNodes.Cast<XmlNode>()
.SingleOrDefault(node => node.Name == "first");
if (firstNode != null)
{
firstNode.InnerText = "1";
}
}
string newxml = NewXml.OuterXml;
It would be strongly recommended using LINQ to XML, it's simpler:
var xDoc = XDocument.Parse(OldXml);
foreach (var element in xDoc.Descendants("first"))
element.SetValue(1);
string newXml = xDoc.ToString();
Your iteration never reaches a node called "first". Else it would work fine without saving the NewXml.
You could however use a XElement and iterate over all descendants.
string OldXml = #"<Root>
<Childs>
<first>this is first</first>
<second>this is second </second>
</Childs>
</Root>";
var NewXml = XElement.Parse(OldXml);
foreach (var node in NewXml.Descendants())
{
if (node.Name.LocalName == "first")
{
node.Value = "1";
}
}
var reader = NewXml.CreateReader();
reader.MoveToContent();
string newxml = reader.ReadInnerXml();
<main>
<myself>
<pid>1</pid>
<name>abc</name>
</myself>
<myself>
<pid>2</pid>
<name>efg</name>
</myself>
</main>
that is my XML file named simpan. I have two button. next and previous. What i want to do is, all the info will shows off on the TextBox when the user click the button. The searching node will be based on the pid.
Next button will adding 1 value of pid (let's say pid=2) and it will search on the node that have the same value of pid=2. it also will show the name for the pid=2. (showing name=abc)
Same goes to the previous button where it will reduce 1value of pid (pid=1).
Does anybody knows how to do this?
//-------------EDIT------------------
thanks to L.B, im trying to use his code. however i got an error.
is my implementation of code correct?
private void previousList_Click(object sender, EventArgs e)
{
pid = 14;
XDocument xDoc = XDocument.Parse("C:\\Users\\HDAdmin\\Documents\\Fatty\\SliceEngine\\SliceEngine\\bin\\Debug\\simpan.xml");
var name = xDoc.Descendants("myself")
.First(m => (int)m.Element("PatientID") == pid)
.Value;
textETA.Text = name;
////////////////////
}
int pid = 2;
XDocument xDoc = XDocument.Parse(xml); //Load
var name = xDoc.Descendants("myself")
.First(m => (int)m.Element("pid") == pid)
.Element("name")
.Value;
You can use the following XPath to list all Myself tags, then look for what you want using a simple Linq command:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "file1.xml");
var resNodes = xmlDoc.SelectNodes("//myself");
XmlNode res = null;
var val = textBox1.Text;
var item = from XmlNode x in resNodes
select x;
foreach (var nodP in item) {
foreach (XmlNode nod in nodP.ChildNodes) {
if (nod.InnerText == val) {
res = nodP;
}
}
}
if (res == null)
// not found!
;
else
// show the result
;
Call me old fashioned but you could use an XPath, for example:
string xml =
#"<main>
<myself>
<pid>1</pid>
<name>abc</name>
</myself>
<myself>
<pid>2</pid>
<name>efg</name>
</myself>
</main>";
using System.Xml;
....
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
// Replace "2" in the string below with the desired pid
XmlNode xmlNode =
xmlDocument.DocumentElement.SelectSingleNode("myself/name[../pid=2]");
// xmlNode contains the <name>efg</name> XmlElement. For example:
string name = xmlNode.Value;
If it can match multiple nodes, for example there could be multiple <myself> elements with a child element <pid> set to 2, use the following instead:
foreach(XmlNode xmlNode in
xmlDocument.DocumentElement.SelectNodes("myself/name[../pid=2]"))
{
// xmlNode contains the matching <name> element
}
In both cases, the value can be extracted from the XmlNode using the Value property.
public class simpman
{
private static XElement root = XElement.Load("Simpman.xml");
public static string GetItem(int index)
{
XElement item =
(from element in root.Elements("myself")
where (int)element.Element("pid") == index
select element.Element("name")).SingleOrDefault();
return item != null ? item.Value : "Please check the Index";
}
}
Initialize a static itemIndex to 1 and use it further like itemIndex++ (for Next) and itemIndex-- (for Prev).
private void previousList_Click(object sender, EventArgs e)
{
pid = 14;
XDocument xDoc = XDocument.Load(#"C:\Users\HDAdmin\Documents\Fatty\SliceEngine\SliceEngine\bin\Debug\simpan.xml");
var name = xDoc.Root
.Descendants("myself")
.FirstOrDefault(e => e.Element("pid")
.Value
.Equals(pid.ToString(CultureInfo.InvariantCulture)))
.Element("name")
.Value;
textETA.Text = name;
}
XmlDocument doc = new XmlDocument();
FileStream fs = new FileStream(rootXMLPath, FileMode.Open, FileAccess.Read);
doc.Load(fs);
XmlNode node = doc.DocumentElement;
nodeName = "/main/myself";
var child1 = node.SelectSingleNode(nodeName).ChildNodes[0].FirstChild.InnerXml;
var child2 = node.SelectSingleNode(nodeName).ChildNodes[0].LastChild.InnerXml;
var child3 = node.SelectSingleNode(nodeName).ChildNodes[1].FirstChild.InnerXml;
var child4 = node.SelectSingleNode(nodeName).ChildNodes[1].LastChild.InnerXml;
I currently have the following code:
XPathNodeIterator theNodes = theNav.Select(theXPath.ToString());
while (theNodes.MoveNext())
{
//some attempts i though were close
//theNodes.RemoveChild(theNodes.Current.OuterXml);
//theNodes.Current.DeleteSelf();
}
I have set xpath to what I want to return in xml and I want to delete everything that is looped. I have tried a few ways of deleting the information but it does't like my syntax. I found an example on Microsoft support: http://support.microsoft.com/kb/317666 but I would like to use this while instead of a for each.
Any comments or questions are appreciated.
Why not to use XDocument?
var xmlText = "<Elements><Element1 /><Element2 /></Elements>";
var document = XDocument.Parse(xmlText);
var element = document.XPathSelectElement("Elements/Element1");
element.Remove();
var result = document.ToString();
result will be <Elements><Element2 /></Elements>.
Or:
var document = XDocument.Load(fileName);
var element = document.XPathSelectElement("Elements/Element1");
element.Remove();
document.Savel(fileName);
[Edit] For .NET 2, you can use XmlDocument:
XmlDocument document = new XmlDocument();
document.Load(fileName);
XmlNode node = document.SelectSingleNode("Elements/Element1");
node.ParentNode.RemoveChild(node);
document.Save(fileName);
[EDIT]
If you need to remove all child elements and attributes:
XmlNode node = document.SelectSingleNode("Elements");
node.RemoveAll();
If you need to keep attributes, but delete elements:
XmlNode node = document.SelectSingleNode("Elements");
foreach (XmlNode childNode in node.ChildNodes)
node.RemoveChild(childNode);
string nodeXPath = "your x path";
XmlDocument document = new XmlDocument();
document.Load(/*your file path*/);
XmlNode node = document.SelectSingleNode(nodeXPath);
node.RemoveAll();
XmlNode parentnode = node.ParentNode;
parentnode.RemoveChild(node);
document.Save("File Path");
You can use XmlDocument:
string nodeXPath = "your x path";
XmlDocument document = new XmlDocument();
document.Load(/*your file path*/);//or document.LoadXml(...
XmlNode node = document.SelectSingleNode(nodeXPath);
if (node.HasChildNodes)
{
//note that you can use node.RemoveAll(); it will remove all child nodes, but it will also remove all node' attributes.
for (int childNodeIndex = 0; childNodeIndex < node.ChildNodes.Count; childNodeIndex++)
{
node.RemoveChild(node.ChildNodes[childNodeIndex]);
}
}
document.Save("your file path"));