Is possible to get the start tag string of an XElement?
For example, if i have an xml element like this
<Product Id="101" Name="Product 1">
<Images>
// ..
</Images>
<Description>
// ..
</Description>
</Product>
i want to get only the start tag:
<Product Id="101" Name="Product 1">
I use this for validation feedback purposes.
use query like
XElement xele = XElement.Load("xmlfilename");
XNamespace _XNamespace = XNamespace.Get("namespace url");
IEnumerable<XElement> ProductAttribute = from ele in xele .Descendants(_XNamespace + "Product ")
where ele.Attribute("Id").Value =="101" && ele.Attribute("Name") == "Product 1"
select ele;
Hope it will work for you
Related
how to get xmlnode value based on attribute value in C#.
<Products>
<Error>0</Error>
<Product link="OWN">
<ProductCode>CA</ProductCode>
<ProductType>Account</ProductType>
<ProductSubtype>Current Account</ProductSubtype>
<ProductDescriptionEng>Current Account</ProductDescriptionEng>
<ProductNumber>1234567</ProductNumber>
<ProductCurrency></ProductCurrency>
<ProductCurrencyCode>01</ProductCurrencyCode>
<ProductBalance>899293.003</ProductBalance>
<LoanRef></LoanRef>
<OldLoanRef></OldLoanRef>
<ProductStandardID>00010001</ProductStandardID>
<OldLoanRef></OldLoanRef>
<ProductStatusCode>00</ProductStatusCode>
<ProductStatus>OPEN</ProductStatus>
<ProductCategory>Deposit Account</ProductCategory>
</Product>
</Product>
in the above example i would like to get value of Product Link "OWN" based on passing attribute value (1234567) 1234567.
I have tried following code but it doesn't return value "OWN" from 'Product link" node.
string _accountsXml = GetProducts();
_xmlDoc.LoadXml(_accountsXml);
_productLinkType = _xmlDoc.SelectSingleNode(string.Format("//Products[../ProductNumber = '{0}']", prodNumber));
You do have to add code to get element's attribute value there, possibly minding the case when the right element was not found. Plus be careful with the element names - both in the xpath expression and in the XML.
The following test code would have "OWN" in the link variable:
var doc = XDocument.Parse(#"<?xml version=""1.0""?>
<Products>
<Error>0</Error>
<Product link=""Global""/>
<Product link=""OWN"">
<Some/>
<ProductNumber>1234567</ProductNumber>
<Nodes/>
</Product>
<Product link=""External"">
<ProductNumber>777</ProductNumber>
</Product>
</Products>");
var id = 1234567;
var link = doc
.XPathSelectElement($"//Product[ProductNumber = '{id}']")
?.Attribute("link")
?.Value;
Console.WriteLine($"Product link: {link ?? "not found"}");
Try this
_productLinkType = _xmlDoc.SelectSingleNode(string.Format("//Products[..//ProductNumber = '{0}']", prodNumber));
or
var xDoc = XDocument.Load(_accountsXml);
var productLinkType = xDoc.XPathSelectElement(string.Format("//Products[..//ProductNumber = '{0}']", prodNumber)).Element("Product").Attribute("link").Value;
The closing tag in your example is Product it should be Products
My C# code:
XDocument doc = XDocument.Load(filename);
IEnumerable<XElement> collection =
doc.Elements("BCIRequest").Elements("Card").Elements("SelectedPIN");
My XML document:
<?xml version="1.0" encoding="utf-8"?>
<BCIRequest Version="2.0"
xmlns="urn:xxxxxx:bci:request">
<Header>
<SenderCode>XX99</SenderCode>
<SenderID>9999</SenderID>
<SequenceNumber>123</SequenceNumber>
<CardGroupCount>2</CardGroupCount>
<CardCount>4</CardCount>
<BlockCount>2</BlockCount>
</Header>
<!--card groups (must precede cards and blocks)-->
<CardGroup RequestID="1">
<CustomerNumber>XX01234567</CustomerNumber>
<CardGroupName Emboss="true">GROUP ONE</CardGroupName>
</CardGroup>
<CardGroup RequestID="2"
RequestRef="87416CB7-DAEF-483A-BD08-1A885531D958">
<CustomerNumber>XX12345678</CustomerNumber>
<CardGroupName Emboss="false">GROUP TWO</CardGroupName>
</CardGroup>
<Card RequestID="3">
<CustomerNumber>XX01234567</CustomerNumber>
<DriverCard>
<Driver Emboss="true">MARGE SIMPSON</Driver>
</DriverCard>
<CardTypeID>10</CardTypeID>
<PurchaseCategoryID>11</PurchaseCategoryID>
<Reissue>false</Reissue>
<GeneratedPIN/>
<OdoPrompt>false</OdoPrompt>
<CRNPrompt>false</CRNPrompt>
</Card>
<Card RequestID="4">
<CustomerNumber>XX12345678</CustomerNumber>
<VehicleCard>
<VRN Emboss="true">KYI 830</VRN>
</VehicleCard>
<CardTypeID>10</CardTypeID>
<PurchaseCategoryID>11</PurchaseCategoryID>
<Reissue>false</Reissue>
<SelectedPIN>0123</SelectedPIN>
<OdoPrompt>false</OdoPrompt>
<CRNPrompt>false</CRNPrompt>
</Card>
<Card RequestID="5">
<CustomerNumber>XX01234567</CustomerNumber>
<BearerCard>
<Bearer Emboss="true">OPEN XXXXXX</Bearer>
</BearerCard>
<CardTypeID>10</CardTypeID>
<PurchaseCategoryID>11</PurchaseCategoryID>
<Reissue>false</Reissue>
<FleetPIN/>
<OdoPrompt>false</OdoPrompt>
<CRNPrompt>false</CRNPrompt>
</Card>
<Block RequestID="6">
<CustomerNumber>XX01234567</CustomerNumber>
<PAN>7002999999999999991</PAN>
</Block>
<Card RequestID="7"
RequestRef="956EA6C5-7D7E-4622-94D0-38CAD9FCC8DF">
<CustomerNumber>XX01234567</CustomerNumber>
<DriverCard>
<Driver Emboss="true">HOMER SIMPSON</Driver>
<VRN Emboss="true">795 DVI</VRN>
</DriverCard>
<EmbossText>SPRINGFIELD POWER</EmbossText>
<CardTypeID>10</CardTypeID>
<TokenTypeID>20</TokenTypeID>
<PurchaseCategoryID>30</PurchaseCategoryID>
<ExpiryDate>2018-12</ExpiryDate>
<Reissue>true</Reissue>
<SelectedPIN>0123</SelectedPIN>
<OdoPrompt>true</OdoPrompt>
<CRNPrompt>true</CRNPrompt>
<!--address with optional fields specified-->
<CardDeliveryAddress OneTimeUse="false">
<ContactName>M xxxx</ContactName>
<ContactTitle>Mr</ContactTitle>
<CompanyName>Sxxxx</CompanyName>
<Line1>Sector 22-F</Line1>
<Line2>Springfield Power Plant</Line2>
<Line3>xxx Road</Line3>
<City>xxxx</City>
<Zipcode>xxxx</Zipcode>
<CountryCode>xxx</CountryCode>
</CardDeliveryAddress>
<!--address with only required fields-->
<PINDeliveryAddress OneTimeUse="true">
<Line1>xxxx</Line1>
<City>xxx</City>
<Zipcode>xxxx</Zipcode>
<CountryCode>xxxx</CountryCode>
</PINDeliveryAddress>
<Limits>
<Value Transaction="unlimited" Daily="200" Weekly="unlimited" Monthly="400"/>
<Volume Transaction="100" Daily="unlimited" Weekly="unlimited" Monthly="unlimited"/>
<Transactions Daily="unlimited" Weekly="unlimited" Monthly="unlimited"/>
<Day Monday="true" Tuesday="true" Wednesday="true" Thursday="true" Friday="true" Saturday="false" Sunday="false"/>
<Time Start="unlimited" End="17:00:00"/>
</Limits>
<Products>
<FuelProductRestrictionID>40</FuelProductRestrictionID>
<NonFuelProductRestrictionID>51</NonFuelProductRestrictionID>
<NonFuelProductRestrictionID>52</NonFuelProductRestrictionID>
<NonFuelProductRestrictionID>53</NonFuelProductRestrictionID>
<NonFuelProductRestrictionID>54</NonFuelProductRestrictionID>
<NonFuelProductRestrictionID>55</NonFuelProductRestrictionID>
</Products>
</Card>
<Block RequestID="8"
RequestRef="69A3E44D-DC10-4BEE-9249-1FC3C651BA0E">
<CustomerNumber>xxxxx</CustomerNumber>
<PAN>xxxxxx</PAN>
</Block>
</BCIRequest>
I need to update the element value in the above values. The old value is:
<SelectedPIN>0123</SelectedPIN>
And the new value should be:
<SelectedPIN EncryptedPIN="TKDS" FormNumber="000793906306">****</SelectedPIN>
Can anyone can help me on this?
If I selected the BCIRequest element, it's returning a null value. I've tried many solutions but unable to get one working on this XML file.
There many ways an Xml can be be modified, I prefer XDocument
XDocument doc = XDocument.Parse(input);
foreach (var element in doc.Descendants("SelectedPIN")) // filter if you want single element, in example I modifed for all elements.
{
element.Add(new XAttribute("EncryptedPIN", "TKDS"));
element.Add(new XAttribute("FormNumber", "000793906306"));
element.Value = "xxxxx"; //new value
}
and finally you can save the document using
doc.Save();
Take a look at this Demo
The root node (BCIRequest) contains a namespace so you need to include that into your query. Something like this should work:
XNamespace ns = "urn:xxxxxx:bci:request";
IEnumerable<XElement> collection = doc.Elements(ns + "BCIRequest").Elements(ns + "Card").Elements(ns + "SelectedPIN");
I have an XML file with code:
<?xml version="1.0" encoding="utf-8"?>
<car_ads>
<car_make make="suzuki" adj_kw="null">
<model data_type="string"adj_kw="null" class="کار_ماڈل ">
<model_instance>ALTO</model_instance>
<model_instance>KHYBER</model_instance>
</model>
<year data_type="integer" adj_kw="yes" class="ایر ">
<adj_kw>ماڈل </adj_kw>
<adj_kw>ء</adj_kw>
</year>
<price data_type="string" adj_kw="yes" class=" قیمت " >
<adj_kw>قیمت </adj_kw>
<adj_kw>ڈیمانڈ </adj_kw>
</price>
</car_make>
<car_make make="سوزوکی" adj_kw="null">
<model data_type="string" adj_kw="null" class="کار_ماڈل ">
<model_instance>alto</model_instance>
<model_instance>آلٹو</model_instance>
</model>
<year data_type="integer" adj_kw="yes" class="ایر ">
<adj_kw>ماڈل </adj_kw>
<adj_kw>ء</adj_kw>
<adj_kw>ایئرآفمینوفیکچرنگ </adj_kw>
</year>
<price data_type="string" adj_kw="yes" class=" قیمت " >
<adj_kw>قیمت </adj_kw>
<adj_kw>ڈیمانڈ </adj_kw>
</price>
</car_make>
</car_ads>
I am parsing this using XmlDocument in c#
string xmlText = File.ReadAllText(#"G:\\car_xml_final.xml");
var doc = new XmlDocument();
doc.LoadXml(xmlText);
If I know attribute value (e.g.in my example attribute class =" ایر") I want to get its corresponding element name (i.e element= "year").
Thanks #Charles Mager for pointing out the difference between XmlDocument and XDocument. If you use XDocument, you can use either LINQ:
var element = doc.Root.Descendants().FirstOrDefault(e => e.Attribute("class") == " ایر");
var elementName = element.Name;
or XPath:
var element = doc.XPathSelectElement("//[#class=' ایر']");
var elementName = element.Name;
to get your desired result.
If you stick to XmlDocument, there's the SelectSingleNode method:
var element = doc.DocumentElement.SelectSingleNode("descendant::[class=""' ایر'""]");
As mentioned in the other answer, you can use SelectSingleNode() or SelectNodes() to get sepcific element(s) from XmlDocument passing an XPath expression as parameter, for example :
var result = doc.SelectNodes("//*[#class='ایر ']");
foreach (XmlNode node in result)
{
//print element name
Console.WriteLine(node.Name);
}
brief explanation about XPath being used :
//* : select all elements regardless of the name (*), anywhere in the XML document (//)...
[#class='some_class_here'] : ...having class attribute value equals certain class name
I have an XML file
<Person>
<PersonItem id="0">
<Time>1/8/2014</Time>
<Step><![CDATA[Normal]]></Step>
<HasAddress/>
<Address/>
</PersonItem>
<PersonItem id="1">
<Time>1/8/2014 3:21:45 PM</Time>
<Step><![CDATA[Normal]]></Step>
<HasAddress/>
<Address/>
</PersonItem>
<PersonItem id="2">
<Time>1/8/2014</Time>
<Step><![CDATA[Normal]]></Step>
<HasAddress>Main</HasAddress>
<Address>
<AddressItem id="0" location=5>
<Address>15 Oak</Address>
</AddressItem>
<AddressItem id="1" location=7>
<Address>12 Maple</Address>
</AddressItem>
<AddressItem id="2" location=8>
<Address>30 Beech</Picture>
</AddressItem>
</Address>
</PersonItem>
</Person>
I want to put to retrieve the information and send some of it to a database. I've tried several different ways of dealing with this and I believe I'm close. Here is the Linq I tried.
public void DoIt(fileName)
{
XElement xml = XElement.Load(fileName);
var items = from item in xml.Elements("PersonItem")
where (from x in item.Elements("HasAddress")
where x.Element("HasAddress") != null
select x).Any()
select item;
Array.ForEach(items.ToArray(),
o=>Console.WriteLine(o.Element("Time").Value));
Console.ReadLine();
}
The problem is nothing is being returned.
Could be just a typo but in your xml file there is this tag error.
<Address>30 Beech</Picture>
which should be:
<Address>30 Beech</Address>
Try this:
XElement xml = XElement.Load(fileName);
var items = xml.Descendants("PersonItem")
.Where(x => (string)x.Element("HasAddress") != null)
.Select(x => x);
XDocument xml = XDocument.Load("Input.xml");
var items = from item in xml.Root.Elements("PersonItem")
where !string.IsNullOrEmpty((string)item.Element("HasAddress"))
select item;
For your sample XML document returns only the last PersonItem element.
I have a whole XML document in a String which i need to convert to a XML document and parse tags in the document
This code sample is taken from csharp-examples.net, written by Jan Slama:
To find nodes in an XML file you can use XPath expressions. Method XmlNode.SelectNodes returns a list of nodes selected by the XPath string. Method XmlNode.SelectSingleNode finds the first node that matches the XPath string.
XML:
<Names>
<Name>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
</Name>
<Name>
<FirstName>James</FirstName>
<LastName>White</LastName>
</Name>
</Names>
CODE:
XmlDocument xml = new XmlDocument();
xml.LoadXml(myXmlString); // suppose that myXmlString contains "<Names>...</Names>"
XmlNodeList xnList = xml.SelectNodes("/Names/Name");
foreach (XmlNode xn in xnList)
{
string firstName = xn["FirstName"].InnerText;
string lastName = xn["LastName"].InnerText;
Console.WriteLine("Name: {0} {1}", firstName, lastName);
}
Using Linq to xml
Add a reference to System.Xml.Linq
and use
XDocument.Parse(string xmlString)
Edit: Sample follows, xml data (TestConfig.xml)..
<?xml version="1.0"?>
<Tests>
<Test TestId="0001" TestType="CMD">
<Name>Convert number to string</Name>
<CommandLine>Examp1.EXE</CommandLine>
<Input>1</Input>
<Output>One</Output>
</Test>
<Test TestId="0002" TestType="CMD">
<Name>Find succeeding characters</Name>
<CommandLine>Examp2.EXE</CommandLine>
<Input>abc</Input>
<Output>def</Output>
</Test>
<Test TestId="0003" TestType="GUI">
<Name>Convert multiple numbers to strings</Name>
<CommandLine>Examp2.EXE /Verbose</CommandLine>
<Input>123</Input>
<Output>One Two Three</Output>
</Test>
<Test TestId="0004" TestType="GUI">
<Name>Find correlated key</Name>
<CommandLine>Examp3.EXE</CommandLine>
<Input>a1</Input>
<Output>b1</Output>
</Test>
<Test TestId="0005" TestType="GUI">
<Name>Count characters</Name>
<CommandLine>FinalExamp.EXE</CommandLine>
<Input>This is a test</Input>
<Output>14</Output>
</Test>
<Test TestId="0006" TestType="GUI">
<Name>Another Test</Name>
<CommandLine>Examp2.EXE</CommandLine>
<Input>Test Input</Input>
<Output>10</Output>
</Test>
</Tests>
C# usage...
XElement root = XElement.Load("TestConfig.xml");
IEnumerable<XElement> tests =
from el in root.Elements("Test")
where (string)el.Element("CommandLine") == "Examp2.EXE"
select el;
foreach (XElement el in tests)
Console.WriteLine((string)el.Attribute("TestId"));
This code produces the following output:
0002
0006
Depending on what document type you want you can use XmlDocument.LoadXml or XDocument.Load.
Try this code:
var myXmlDocument = new XmlDocument();
myXmlDocument.LoadXml(theString);