how can i read an Id from the below sample XML >>> CatalogItem Id="3212" and OrganizationName
string xmlfile = #"C:\Users\easwaranp\Desktop\test.xml";
ArrayList arrResult = new ArrayList();
string sContent = File.ReadAllText(xmlfile);
StringReader DocumentReader = new StringReader(sContent);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(DocumentReader);
XmlNodeList ReferenceNodes = xmlDoc.GetElementsByTagName("content:Topic");
foreach (XmlNode Node in ReferenceNodes)
{
string sTopicName = Node.ParentNode.ParentNode.Attributes["OrganizationName"].Value;
}
foreach (string s in arrResult)
{
Console.WriteLine(s);
}
Console.Read();
<content type="application/xml">
<CatalogItems xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="sitename.xsd">
<CatalogSource Acronym="ABC" OrganizationName="ABC Corporation" />
<CatalogItem Id="32122" CatalogUrl="urlname">
<ContentItem xmlns:content="sitename.xsd" Title="Department 1">
<content:SelectionSpec ClassList="" ElementList="" />
<content:Language Value="eng" Scheme="ISO 639-2" />
<content:Source Acronym="ABC" OrganizationName="ABC Corporation1" />
<content:Topics Scheme="ABC">
<content:Topic TopicId="1" TopicName="Marketing1" />
<content:Topic TopicId="11" TopicName="Coverage1" />
</content:Topics>
</ContentItem>
</CatalogItem>
<CatalogItem Id="3212" CatalogUrl="urlname">
<ContentItem xmlns:content="sitename.xsd" Title="Department 2">
<content:SelectionSpec ClassList="" ElementList="" />
<content:Language Value="eng" Scheme="ISO 639-2" />
<content:Source Acronym="ABC" OrganizationName="ABC Corporation2" />
<content:Topics Scheme="ABC">
<content:Topic TopicId="2" TopicName="Marketing2" />
<content:Topic TopicId="22" TopicName="Coverage2" />
</content:Topics>
</ContentItem>
</CatalogItem>
<CatalogItem Id="32132" CatalogUrl="urlname">
<ContentItem xmlns:content="sitename.xsd" Title="Department 3">
<content:SelectionSpec ClassList="" ElementList="" />
<content:Language Value="eng" Scheme="ISO 639-2" />
<content:Source Acronym="ABC" OrganizationName="ABC Corporation3" />
<content:Topics Scheme="ABC">
<content:Topic TopicId="3" TopicName="Marketing3" />
<content:Topic TopicId="33" TopicName="Coverage3" />
</content:Topics>
</ContentItem>
</CatalogItem>
</CatalogItems>
</content>
using System;
using System.IO;
using System.Xml;
class GetValue{
public static void Main(){
var xmlDoc = new XmlDocument();
xmlDoc.Load("test.xml");
var xmlRoot = xmlDoc.DocumentElement;
var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("content", "sitename.xsd");
var attr = xmlRoot.SelectSingleNode("descendant::content:Source/#OrganizationName[../../../#Id='3212']", nsmgr);
if(attr == null)
Console.WriteLine("not found!");
else
Console.WriteLine(attr.Value);
}
}
OUTPUT:
ABC Corporation2
XPath is your friend when it comes to tasks like this. I adapted the following code from a tutorial on codeproject.com. I don't know if it works (or will even compile), but it should get you started in the right direction. Also, I'm assuming your talking about C#, but in case I've misunderstood what language you're using, please disregard (a language tag on your question might help).
using System.Xml;
using System.Xml.XPath;
....
string fileName = "test.xml";
XPathDocument doc = new XPathDocument(fileName);
XPathNavigator nav = doc.CreateNavigator();
// Compile a standard XPath expression
XPathExpression expr;
idExpr = nav.Compile("/content/CatalogItems/CatalogItem/#id");
XPathNodeIterator iterator = nav.Select(idExpr);
// Iterate on the node set
try
{
while (iterator.MoveNext())
{
XPathNavigator nav2 = iterator.Current.Clone();
Console.WriteLine("id: " + nav2.Value);
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
Related
I have an XML file with several customers. When the customer ID is duplicated, I want to take the service from the duplicate customer record and add it to the initial customer record. I'm trying to do this in C#.
So the following two records:
<customer ID="200054598540" phone="352-555-1234" name="PAULSON ROBERT">
<services>
<service type="Electric" premise="5000001234" priority="0" />
</services>
<customFields>
<customField key="address" value="1521 NE 23RD AVE" />
<customField key="connection" value="CONNECTED" />
</customFields>
</customer>
<customer ID="200054598540" phone="352-555-1234" name="PAULSON ROBERT">
<services>
<service type="Water" premise="5000001235" priority="0" />
</services>
<customFields>
<customField key="address" value="1521 NE 23RD AVE" />
<customField key="connection" value="CONNECTED" />
</customFields>
</customer>
Become one, and it removes the duplicate, leading to:
<customer ID="200054598540" phone="352-555-1234" name="PAULSON ROBERT">
<services>
<service type="Electric" premise="5000001234" priority="0" />
<service type="Water" premise="5000001235" priority="0" />
</services>
<customFields>
<customField key="address" value="1521 NE 23RD AVE" />
<customField key="connection" value="CONNECTED" />
</customFields>
</customer>
private static void combineDuplicates()
{
XDocument doc = XDocument.Load(#"C:\customer_premise_osi_oms\customers.xml");
var customers = doc.Descendants("customer").GroupBy(x => (string)x.Attribute("ID")).ToList();
foreach (var customer in customers)
{
XElement firstAccount = customer.FirstOrDefault();
XElement firstServices = firstAccount.Element("services");
XElement firstCustomerField = firstAccount.Element("customFields");
for (int i = customer.Count() - 1; i >= 1; i--)
{
XElement account = customer.Skip(i).FirstOrDefault();
List<XElement> services = account.Descendants("service").ToList();
firstServices.Add(services);
//List<XElement> customFields = account.Descendants("customField").ToList();
//firstCustomerField.Add(customFields);
account.Remove();
}
}
doc.Save(#"c:\customer_premise_osi_oms\customers_dupe.xml");
}
Using Xml Linq :
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication75
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var customers = doc.Descendants("customer").GroupBy(x => (string)x.Attribute("ID")).ToList();
foreach (var customer in customers)
{
XElement firstAccount = customer.FirstOrDefault();
XElement firstServices = firstAccount.Element("services");
XElement firstCustomerField = firstAccount.Element("customFields");
for (int i = customer.Count() - 1; i >= 1; i--)
{
XElement account = customer.Skip(i).FirstOrDefault();
List<XElement> services = account.Descendants("service").ToList();
firstServices.Add(services);
List<XElement> customFields = account.Descendants("customField").ToList();
firstCustomerField.Add(customFields);
account.Remove();
}
}
}
}
}
my xml file is like below:
<?xml version="1.0"?>
<UpdateInboundim613Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" status="SUCCESS" message="Success" schemaRevisionDate="2016-07-19" schemaRevisionLevel="0" returnCode="0" xmlns="http://schemas.hp.com/SM/7">
<model>
<keys>
<TransactionID type="String">E-InHPSXIM1089779</TransactionID>
</keys>
<instance uniquequery="TransactionID="E-InHPSXIM1089779"" recordid="E-InHPSXIM1089779">
<TransactionDetailedTrace xsi:nil="true" />
<TransactionMessage type="Array">
<TransactionMessage type="String" />
</TransactionMessage>
<OVSCSolutionDescription type="Array">
<OVSCSolutionDescription type="String">Issue: EL-BANK OUTSIDE WAREHOUSE EGYPT IMEA[2702]Interface[[E1 0/0/0]]|Router|ELBKCE1GW /pg-h-pg1252-256675160|143.34.213.18|Down Solution: As per update from Mai Shrief that the site has been suspended on 30th June. So no need of any investigation. Resolved By: BT NOC</OVSCSolutionDescription>
</OVSCSolutionDescription>
<OVSCTicketID type="String">E-IM004004076</OVSCTicketID>
<RIMSImpact xsi:nil="true" />
<attachments />
</instance>
</model>
<messages>
<message type="String" xmlns="http://schemas.hp.com/SM/7/Common">TransactionStatusDetail in $L.file is:IM Ticket: E-IM004004076 is valid for Update Subtype: Resolve</message>
</messages>
</UpdateInboundim613Response>
but my code cannot get value of element "OVSCTicketID":
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"C:\zzx\Project\SM\R5.1\Harness\InBound.xml");
XmlNode sigNode = xmlDoc.SelectSingleNode("/UpdateInboundim613Response/model/instance/OVSCTicketID");
if (sigNode != null)
{
Console.WriteLine(sigNode.InnerText);
}
can you please tell me what's the problem and how to fix it?
Your Xml document uses the default namespace "http://schemas.hp.com/SM/7". You need to use the XmlNamespaceManager to select that node under this namespace.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"C:\zzx\Project\SM\R5.1\Harness\InBound.xml");
var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
namespaceManager.AddNamespace("ns", "http://schemas.hp.com/SM/7");
XmlNode sigNode = xmlDoc.SelectSingleNode("//ns:UpdateInboundim613Response//ns:model//ns:instance//ns:OVSCTicketID",namespaceManager);
if (sigNode != null)
{
Console.WriteLine(sigNode.InnerText);
}
Above code should work fine.
Using xml linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XNamespace defaultNs = ((XElement)doc.FirstNode).GetDefaultNamespace();
string ovsCTicketID = (string)doc.Descendants(defaultNs + "OVSCTicketID").FirstOrDefault();
}
}
}
I have simple loop for finding child Element:
XDocument xDoc = XDocument.Load(#"bpmn.xml");
//Run query
foreach (XElement level1Element in xelement.Elements("process"))
{
System.Diagnostics.Debug.WriteLine(level1Element.Attribute("id").Value);
foreach (XElement level2Element in level1Element.Elements("task"))
{
System.Diagnostics.Debug.WriteLine(
" " + level2Element.Attribute("name").Value);
}
}
Why don't I get any output?
The input XML:
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://sourceforge.net/bpmn/definitions/_1384266732154" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:yaoqiang="http://bpmn.sourceforge.net" exporter="Yaoqiang BPMN Editor" exporterVersion="2.2.18 (GPLv3, Non-Commercial)" expressionLanguage="http://www.w3.org/1999/XPath" id="_1384266732154" name="" targetNamespace="http://sourceforge.net/bpmn/definitions/_1384266732154" typeLanguage="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://bpmn.sourceforge.net/schemas/BPMN20.xsd"> <collaboration id="COLLABORATION_1" isClosed="false">
<participant id="_2" name="CEO" processRef="PROCESS_1">
<participantMultiplicity maximum="1" minimum="0"/>
</participant>
<participant id="_3" name="Manager" processRef="PROCESS_2">
<participantMultiplicity maximum="1" minimum="0"/>
</participant>
<participant id="_4" name="project Manager" processRef="PROCESS_3">
<participantMultiplicity maximum="1" minimum="0"/>
</participant>
<participant id="_5" name="HR" processRef="PROCESS_4">
<participantMultiplicity maximum="1" minimum="0"/>
</participant>
<participant id="_6" name="Employee" processRef="PROCESS_5">
<participantMultiplicity maximum="1" minimum="0"/>
</participant> </collaboration> <process id="PROCESS_1" isClosed="false" isExecutable="true" processType="None">
<startEvent id="_8" isInterrupting="true" name="Start Event" parallelMultiple="false">
<outgoing>_12</outgoing>
</startEvent>
<task completionQuantity="1" id="_9" isForCompensation="false" name="Task" startQuantity="1">
<incoming>_12</incoming>
<outgoing>_13</outgoing>
</task>
<sendTask completionQuantity="1" id="_10" implementation="##WebService" isForCompensation="false" name="Send Task" startQuantity="1">
<incoming>_13</incoming>
<outgoing>_14</outgoing>
</sendTask>
<task completionQuantity="1" id="_11" isForCompensation="false" name="Task" startQuantity="1">
<incoming>_14</incoming>
</task>
<sequenceFlow id="_12" sourceRef="_8" targetRef="_9"/>
<sequenceFlow id="_13" sourceRef="_9" targetRef="_10"/>
<sequenceFlow id="_14" sourceRef="_10" targetRef="_11"/> </process> <process id="PROCESS_2" isClosed="false" isExecutable="true" processType="None">
<task completionQuantity="1" id="_17" isForCompensation="false" name="Task" startQuantity="1">
<outgoing>_21</outgoing>
</task>
<task completionQuantity="1" id="_19" isForCompensation="false" name="Task" startQuantity="1">
<incoming>_21</incoming>
<outgoing>_23</outgoing>
<outgoing>_25</outgoing>
</task>
<sequenceFlow id="_21" sourceRef="_17" targetRef="_19"/>
<receiveTask completionQuantity="1" id="_22" implementation="##WebService" instantiate="false" isForCompensation="false" name="Receive Task" startQuantity="1">
<incoming>_23</incoming>
</receiveTask>
<sequenceFlow id="_23" name="go on" sourceRef="_19" targetRef="_22"/>
<task completionQuantity="1" id="_24" isForCompensation="false" name="Task" startQuantity="1">
<incoming>_25</incoming>
</task>
<sequenceFlow id="_25" sourceRef="_19" targetRef="_24"/> </process> </definitions>
You need to get the root element first, by xDoc.Root (if xelement in your code is xDoc)
(The main problem here) Your XML has a custom namespace, in which case you need to specify it when calling Elements().
Putting together:
XDocument xDoc = XDocument.Load(#"bpmn.xml");
var ns = XNamespace.Get("http://www.omg.org/spec/BPMN/20100524/MODEL");
//Run query
foreach(XElement level1Element in xDoc.Root.Elements(ns + "process"))
{
System.Diagnostics.Debug.WriteLine(level1Element.Attribute("id").Value);
foreach(XElement level2Element in level1Element.Elements(ns + "task"))
{
System.Diagnostics.Debug.WriteLine(" " + level2Element.Attribute("name").Value);
}
}
You need to select from the root element. Try changing:
xelement.Elements("process"))
To:
xDoc.Elements("definitions").Elements("process")
Your .xml file provided with namespace, still you should use it in your code. Please try this:
XDocument xDoc = XDocument.Load(#"xmlfile1.xml");
//Run query
XNamespace ns = "http://www.omg.org/spec/BPMN/20100524/MODEL";
foreach (XElement level1Element in xDoc.Descendants(ns + "process"))
{
System.Diagnostics.Debug.WriteLine(level1Element.Attribute("id").Value);
foreach (XElement level2Element in level1Element.Elements(ns + "task"))
{
System.Diagnostics.Debug.WriteLine(
" " + level2Element.Attribute("name").Value);
}
}
Also, in your case use Descendants() method instead of Elements().
More info http://msdn.microsoft.com/en-us/library/system.xml.linq.xname(v=vs.110).aspx
first, sorry for my bad english, i'm learning yet. So, I have to delete specifics nodes of a xml file according with their attributes. This is the xml file:
<?xml version="1.0" encoding="utf-8"?>
<Lista>
<Indice value="8">
<Palavra value="casa" />
<Significados>s1,,,,</Significados>
</Indice>
<Indice value="49">
<Palavra value="teste" />
<Significados>1,2,,,</Significados>
</Indice>
<Indice value="72">
<Palavra value="cristiano" />
<Significados>ornelas,ribeiro,,,</Significados>
</Indice>
<Indice value="72">
<Palavra value="teste2" />
<Significados>s2,s3,,,</Significados>
</Indice>
</Lista>
I have to delete all Indice nodes and your childrens that have the attribute value="72" for example. How can I do that? The language is c# and the xml file after of delete must stay in this form:
<?xml version="1.0" encoding="utf-8"?>
<Lista>
<Indice value="8">
<Palavra value="casa" />
<Significados>s1,,,,</Significados>
</Indice>
<Indice value="49">
<Palavra value="teste" />
<Significados>1,2,,,</Significados>
</Indice>
</Lista>
XDocument xdoc=XDocument.Parse(xmlStr); //or XDocument.Load
var matchingElements = xdoc.Root
.Descendants("Indice")
.Where(e => (int)e.Attribute("value") == 72)
.ToList();
foreach(var elem in matchingElements)
{
elem.Remove();
}
xdoc.Save(newFileName);
saves the following doc:
<Lista>
<Indice value="8">
<Palavra value="casa" />
<Significados>s1,,,,</Significados>
</Indice>
<Indice value="49">
<Palavra value="teste" />
<Significados>1,2,,,</Significados>
</Indice>
</Lista>
This is an alternative to Spender although he should get the question answered if his works.
XmlDocument doc = new XmlDocument();
doc.Load("xml path");
XmlNode node = doc.SelectSingleNode("/Lista");
foreach (XmlNode nodes in node.SelectNodes("Indice/#value"))
{
if (nodes.Value == "72")
{
nodes.RemoveAll();
}
}
i am experimenting with C# and xml, i am trying to read a XML file i want to validate if "NumberOfDays" , "NumberOfBooks", "NumberOfExam", "CurrentDate" are existing, if missing. i want to add them with there values.
i have the following xmldocument :
<?xml version="1.0" encoding="utf-8" ?>
<MySample>
<Content>
<add key="NumberOfDays" value="31" />
<add key="NumberOfBooks" value="20" />
<add key="NumberOfExam" value="6" />
<add key="CurrentDate" value="15 - Jul - 2011" />
</Content>
</MySample>
i am writing a sample application in c# using
--------Edit--------
thank you AresAvatar for your responce.
but if the value exists i would like to update its value i.e. if let's say
<add key="NumberOfExam" value="" />
i want to change the value to 6
You can get a list of which nodes exist like this:
// Get a list of which nodes exist
XmlDocument doc = new XmlDocument();
doc.LoadXml(myXml);
List<string> existingNodes = new List<string>();
XmlNodeList bookNodes = doc.SelectNodes("/MySample/Content/add");
foreach (XmlNode nextNode in bookNodes)
{
foreach (XmlAttribute nextAttr in nextNode.Attributes)
existingNodes.Add(nextAttr.InnerText);
}
You can add missing nodes like this:
// Add nodes
XmlNode addRoot = doc.SelectSingleNode("/MySample/Content");
XmlElement addme = doc.CreateElement("add");
addme.SetAttribute("NumberOfDays", "31");
addRoot.AppendChild(addme);
You can set the value of existing nodes like this:
// Update a node
foreach (XmlNode nextNode in bookNodes)
{
foreach (XmlAttribute nextAttr in nextNode.Attributes)
{
switch (nextAttr.Name)
{
case "NumberOfDays":
((XmlElement)nextNode).SetAttribute("value", "31");
break;
// etc.
}
}
}
First of all, if you have control over the generated XML (if you make it yourself), avoid using this schema:
<?xml version="1.0" encoding="utf-8" ?>
<MySample>
<Content>
<add key="NumberOfDays" value="31" />
<add key="NumberOfBooks" value="20" />
<add key="NumberOfExam" value="6" />
<add key="CurrentDate" value="15 - Jul - 2011" />
</Content>
</MySample>
It's much easier to use with that schema:
<?xml version="1.0" encoding="utf-8" ?>
<MySample>
<Content>
<Adds>
<NumberOfDays>31<NumberOfDays/>
<NumberOfBooks>20<NumberOfBooks/>
<NumberOfExam>6<NumberOfExam/>
<CurrentDate>5 - Jul - 2011<CurrentDate/>
</Adds>
</Content>
</MySample>
And then:
XmlDocument doc = new XmlDocument();
doc.Load("YourXmlPath");
XmlNode firstNode = doc["MySample"];
if(firstNode != null)
{
XmlNode secondNode = firstNode["Content"];
if(secondNode != null)
{
XmlNode thirdNode = secondNode["Adds"];
if(thirdNode != null)
{
if(thirdNode["NumberOfDays"] == null) //The "NumberOfDays" node does not exist, we create it.
{
XmlElement newElement = doc.CreateElement("NumberOfDays");
newElement.InnerXml = 31;
thirdNode.AppendChild(newElement);
}
//Do the same for the other nodes...
}
}
}
doc.Save("YourXmlPath");
Just remember to check for null on every node, or put the whole block into a try/catch.
And to save the XML once you did your changes.
XmlDocument.Load() function loads the XML in memory, so you can check for any node without making "blind loops".