I want to access an attribute type where the value of abc is female
XElement xelement = XElement.Load("..\\..\\Employees.xml");
var name = from nm in xelement.Elements("Employee")
where (string)nm.(Element("Abc") == "Female").Attribute("Type") == "Att"
select nm;
This didn't work. Any way to make it happen?
Something like this would work. It would be useful to see the Xml though.
var doc = XDocument.Load("c:\\temp\\test.xml");
var result = doc.Descendants("Employee")
.Where(x=>(string)x.Value== "female")
.Select(x=>x.Attribute("type").Value);
This is assuming the xml is something like this, the query would return "foo1".
<?xml version="1.0"?>
<root>-
<Employee type="foo">
<abc>male</abc>
</Employee>
<Employee type="foo1">
<abc>female</abc>
</Employee>
<Employee type="foo2">
<abc>male</abc>
</Employee>
</root>
Your code doesn't make any sense.
You cannot nest comparisons and casts and objects like that.
Instead, you need to use the && operator to check each condition separately.
Use XMLReader
More information from MSDN:http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx
Related
Here is my xml file data
<Persons>
<Person>
<Name>john</Name>
</Person>
<Employee>
<Detail>
<Firstname>john</FirstName>
</Detail>
</Employee>
<Student>
<FullName>john</FullName>
</Student>
</Persons>
I want to replace "john" to "danny" in all places.
How can I do this in c# ?
One possible way using XDocument :
var doc = XDocument.Load("path_to_xml_file.xml");
//select all leaf elements having value equals "john"
var elementsToUpdate = doc.Descendants()
.Where(o => o.Value == "john" && !o.HasElements);
//update elements value
foreach(XElement element in elementsToUpdate)
{
element.Value = "danny";
}
//save the XML back as file
doc.Save("path_to_xml_file.xml");
Notice that XElement.Value contains all text nodes within the element, concatenated.
The significance of this is, for example, considering your XML as input, not only <Name> has value of "john" but also <Person>. But we only want to update the leaf elements not the ancestors.
*) I assumed you didn't really meant to tag the question by xmldocument so this answer using the newer XML API XDocument, though using XmlDocument is also possible.
I have below a xml file with the below format:
<?xml version="1.0" encoding="utf-8" ?>
<Root>
<Countries>
<country>India</country>
<country>USA</country>
<country>UK</country>
</Countries>
</Root>
string newCountry="UAE"
I want to insert this "UAE" country to the above xml file, before that I want to check whether "UAE" is already exists in the xml. If not exists then only want to insert otherwise no operation. How can I do this?
Like this:
XDocument xml = XDocument.Load("path_to_file");
string newCountry = "UAE";
XElement countries = xml.Descendants("Countries").First();
XElement el = countries.Elements().FirstOrDefault(x => x.Value == newCountry);
if (el == null)
{
el = new XElement("country");
el.Value = newCountry;
countries.Add(el);
}
//Console.WriteLine(countries.ToString());
The easiest way would probably be to read the xml into C# objects, check for the existance of UAE, potentially add it, and write the objects back to XML.
I have the XSD schema definition loaded (XDocument variable type) I can't figure out how to get the someProperty value. Any ideas ?
<xsd:form-definition xmlns:xsd="http://url/lorem.xsd"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
...
someProperty="ABC">
...
</xsd:form-definition>
Simple with LINQ to XML:
var attributes = (from n in xml.Root.Attributes("someProperty")
select n.Value).ToList();
I stored the xml structure in xml string like abcd variable.test1,test2,test3 are parts of the xml sructure.how to get suffix values like 1,2,3 from test1,test2,test3?
string abcd="<xmlstruct>
<test1>
<name>testname1</name>
<address>testaddress1</address>
<subject>testsub1<subject>
</test1>
<test2>
<name>testname2</name>
<address>testaddress2</address>
<subject>testsub2<subject>
</test2>
<test3>
<name>testname3</name>
<address>testaddress3</address>
<subject>testsub3<subject>
</test3>
</xmlstruct>";
Ideally, don't structure your XML like that in the first place. It's not a good use of element names. It would be better to use:
<test id="1">
...
</test>
<test id="2">
...
</test>
If these are the result of having separate variables in your original classes, that suggests the variables should probably be a single collection instead.
If you really want to find them though, you could use something like this:
IEnumerable<string> ListSuffixes(XElement container, XName prefix)
{
string localPrefix = prefix.Name.LocalName;
var elements = container.Elements()
.Where(x => x.Name.Namespace == prefix.Name.Namespace
&& x.Name.LocalName
.StartsWith(localPrefix));
foreach (var element in elements)
{
yield return element.Name.LocalName.Substring(localPrefix.Length);
}
}
I'm not entirely sure what you are trying to achieve, but this isn't really how XML is normally used.
To obtain the suffixes (1, 2, 3) from a piece of XML that looks like the above then you could parse the XML, select all children of the xmlstruct element and then use string manipulation.
However an alternative schema would probably be a better idea, like storing the suffixes separately as attributes
<xmlstruct>
<test Suffix="1">
<name>testname1</name>
<address>testaddress1</address>
<subject>testsub1<subject>
</test>
<test Suffix="2">
<name>testname2</name>
<address>testaddress2</address>
<subject>testsub2<subject>
</test>
<test Suffix="3">
<name>testname3</name>
<address>testaddress3</address>
<subject>testsub3<subject>
</test>
</xmlstruct>
Element names shouldn't really be dynamic, the list of allowed element names for a given element should normally belong to a fixed (finite) list
You can try this :
Integer.parseInt(s.replaceAll("[\\D]", ""))
This will also remove non-digits inbetween digits, so "test1test1x" becomes 11.
This works:
var suffices =
XDocument
.Parse(abcd)
.Element("xmlstruct")
.Elements()
.Where(xe => xe.Name.ToString().StartsWith("test"))
.Select(xe => int.Parse(xe.Name.ToString().Substring(4)));
It returns:
Im really struggling to get my head round this.
Im using c#.
I want to get back an IEnumerable of products from an xml file.
Below is a sample of the xml structure.
I need to get a list of products that have the productEnriched custom attribute set as true.
Some products wont have any custom attribute section at all
my head has strated to hurt just thinking about it!
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://www.mynamespace.com" catalog-id="MvgCatalog">
<product>
<custom-attributes>
<custom-attribute attribute-id="productEnriched">true</custom-attribute>
</custom-attributes>
</product>
</category>
thanks for any help
To clear things up i have added a few more items to the example xml
I need to get a list of products
only products that have a custom-attribute element with the attribute productEnriched and value of true
some products in the xml wont have any custom-attribute or custom-attributes elements
some products will have it but with a value of false
i just need a list of products where it exists and has a value of true
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="http://www.mynamespace.com" catalog-id="MvgCatalog">
<product>
<upc>000000000000</upc>
<productTitle>My product name</productTitle>
<custom-attributes>
<custom-attribute attribute-id="productEnriched">true</custom-attribute>
<custom-attribute attribute-id="somethingElse">4</custom-attribute>
<custom-attribute attribute-id="anotherThing">otherdata</custom-attribute>
</custom-attributes>
</product>
</category>
I need to get a list of products only products that have a
custom-attribute element with the attribute productEnriched and value
of true some products in the xml wont have any custom-attribute or
custom-attributes elements some products will have it but with a value
of false i just need a list of products where it exists and has a
value of true
var xml = XElement.Load(#"your file.xml");
XNamespace ns = "http://www.mynamespace.com";
var products = xml.Elements(ns + "product");
var filtered = products.Where(
product =>
product.Element(ns + "custom-attributes") != null &&
product.Element(ns + "custom-attributes").Elements(ns + "custom-attribute")
.Any(
ca =>
ca.Value == "true" &&
ca.Attribute("attribute-id") != null &&
ca.Attribute("attribute-id").Value == "productEnriched"));
By the way, your XMLs are not valid - your opening tag (catalog) does not match your closing tag (category).
The format by itself is strange - is it your idea?
<custom-attributes>
<custom-attribute attribute-id="productEnriched">true</custom-attribute>
<custom-attribute attribute-id="somethingElse">4</custom-attribute>
<custom-attribute attribute-id="anotherThing">otherdata</custom-attribute>
</custom-attributes>
Why put an attribute name as an attribute value and attribute value as an element value? It looks bloated and kind of "reinvents" XML with no clear purpose.
Why not:
<custom-attributes>
<custom-attribute productEnriched="true"/>
<custom-attribute somethingElse="4"/>
<custom-attribute anotherThing="otherdata"/>
</custom-attributes>
Or:
<custom-attributes productEnriched="true" somethingElse="4" anotherThing="otherdata"/>
Or perhaps just use elements:
<product-parameters>
<productEnriched>true</productEnriched>
<somethingElse>4</somethingElse>
<anotherThing>otherdata</anotherThing>
</product-parameters>