Reputation: 8014
I have many tags in my XML
<?xml version="1.0" encoding="UTF-8"?>
<xmi:XMI xmlns:util="http://" xmlns:tcas="http://" xmlns:xmi="http://www.omg.org/XMI" xmlns:cas="http:/" xmlns:type10="http:///" xmlns:ne="http:///" xmlns:group3="http:///org/" xmi:version="2.0">
<cas:NULL xmi:id="0"/>
<group1:Black xmi:id="19" code="1" ref="0" mask="23086" id="SIMPLE_Black"/>
<group1:White xmi:id="25" code="2" ref="0" mask="21" WhiteNumber="0"/>
<group1:White xmi:id="31" code="7" ref="23" mask="39" WhiteNumber="1"/>
<group1:White xmi:id="37" code="3" ref="53" mask="68" WhiteNumber="2"/>
<group1:White xmi:id="43" code="7" ref="71" mask="86" WhiteNumber="3"/>
<group1:White xmi:id="49" code="3" ref="88" mask="102" WhiteNumber="4"/>
<group2:Pink xmi:id="8745" code="4" ref="20613" mask="20614" other="5904"/>
<group2:Pink xmi:id="8753" code="7" ref="20624" mask="20625" other="5907"/>
<group2:Pink xmi:id="8761" code="5" ref="20625" mask="20626" other="5908"/>
<group2:Pink xmi:id="8769" code="2" ref="20640" mask="20641" other="5911"/>
<group2:Pink xmi:id="8777" code="1" ref="20641" mask="20642" other="5912"/>
<group2:Pink xmi:id="8785" code="6" ref="20701" mask="20702" other="5923"/>
<group2:Blue xmi:id="31715" code="3" ref="6959" mask="6966" other="2457" />
<group2:Blue xmi:id="31727" code="5" ref="6967" mask="6971" other="2458" />
<group2:Blue xmi:id="31747" code="7" ref="6973" mask="6977" other="2460" />
<group2:Blue xmi:id="31759" code="2" ref="6978" mask="6981" other="2461" />
<group2:Blue xmi:id="31771" code="8" ref="6982" mask="6991" other="2463" />
<group2:Blue xmi:id="31783" code="8" ref="6992" mask="6993" other="2464" />
<group2:Blue xmi:id="31795" code="8" ref="6994" mask="7002" other="2465" />
<group2:Blue xmi:id="31807" code="9" ref="7003" mask="7013" other="2466" />
<group2:Blue xmi:id="31827" code="3" ref="7015" mask="7022" other="2468" />
<group2:Blue xmi:id="31847" code="1" ref="7024" mask="7026" other="2470" />
<group2:Red xmi:id="29184" code="2" ref="6100" mask="6101" other="2178" />
<group2:Red xmi:id="29217" code="1" ref="6105" mask="6106" other="2182" />
<group2:Red xmi:id="29234" code="4" ref="6109" mask="6110" other="2184" />
<group2:Red xmi:id="29278" code="1" ref="6128" mask="6129" other="2188" />
<group2:Yellow xmi:id="30300" code="4" ref="6398" mask="6400" other="2304" />
<group2:Yellow xmi:id="30333" code="1" ref="6404" mask="6406" other="2308" />
<group2:Yellow xmi:id="30394" code="5" ref="6426" mask="6429" other="2314" />
<group2:Yellow xmi:id="30431" code="1" ref="6437" mask="6439" other="2318" />
<group2:Yellow xmi:id="30468" code="6" ref="6447" mask="6450" other="2322" />
<group2:Green xmi:id="79301" code="1" ref="2501" mask="2505" GreenType="NP"/>
<group2:Green xmi:id="79306" code="6" ref="2505" mask="2506" GreenType="O"/>
<group2:Green xmi:id="79311" code="1" ref="2507" mask="2520" GreenType="ADJP"/>
<group2:Green xmi:id="79316" code="1" ref="2521" mask="2523" GreenType="PP"/>
<group2:Green xmi:id="79321" code="1" ref="2524" mask="2542" GreenType="NP"/>
<group3:Brown xmi:id="117792" code="7" ref="16421" mask="16426" id="0" max="0"/>
<group3:Brown xmi:id="119483" code="1" ref="16486" mask="16497" id="0" />
<group3:Brown xmi:id="117469" code="1" ref="16486" mask="16492" id="0" />
<group3:Brown xmi:id="119364" code="8" ref="16493" mask="16497" id="0" />
<group2:Grey xmi:id="137117" code="1" ref="143" mask="150" id="1" />
<group2:Grey xmi:id="137131" code="1" ref="150" mask="151" id="2" />
<group2:Grey xmi:id="137145" code="8" ref="152" mask="159" id="0"/>
<group2:Grey xmi:id="137159" code="1" ref="152" mask="159" id="1" />
<group3:Purple xmi:id="236545" id="0" category="R" argument="236523"/>
<group3:Purple xmi:id="235624" id="0" category="A" argument="235612"/>
<group3:Purple xmi:id="232638" id="0" category="A" argument="232632"/>
<group3:Purple xmi:id="236845" id="0" category="A" argument="236821"/>
<group3:Purple xmi:id="242015" id="0" category="C" argument="242003"/>
</xmi:XMI>
is there a way I can select all tags by name at once something like
xmlnode = xmldoc.GetElementsByTagName("group1:White, group2:Blue, group3:Brown");
Upvotes: 0
Views: 1666
Reputation: 34429
Try 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 xmi = doc.Root.GetNamespaceOfPrefix("xmi");
List<Group> groups = doc.Descendants().Where(x => x.GetPrefixOfNamespace(x.Name.NamespaceName).StartsWith("group")).Select(x => new Group()
{
name = x.Name.LocalName,
color = x.Name.NamespaceName,
id = (int?)x.Attribute(xmi + "id"),
code = (int?)x.Attribute("code"),
_ref = (int?)x.Attribute("ref"),
mask = (int?)x.Attribute("mask"),
whiteNumber = (int?)x.Attribute("WhiteNumber"),
GreenType = (string)x.Attribute("GreenType"),
max = (int?)x.Attribute("max"),
category = (string)x.Attribute("category"),
argument = (int?)x.Attribute("argument"),
other = (int?)x.Attribute("other")
}).ToList();
}
}
public class Group
{
public string name { get; set; }
public string color { get; set; }
public int? xmiid { get; set; }
public int? id { get; set; }
public int? code { get; set; }
public int? _ref { get; set; }
public int? mask { get; set; }
public int? whiteNumber { get; set; }
public int? other { get; set; }
public string GreenType { get; set; }
public int? max { get; set; }
public string category { get; set; }
public int? argument { get; set; }
}
}
Upvotes: 1
Reputation: 708
Ok. so as mentioned by Sajid in your other post - the group1 and group2 are not declared in the posted XML. Ignoring that for now (you'll need to provide us means on how those groups have been declared or manage it by yourself), there is a way to do what you need - instead of your method to get element by the multiple names, you can get all children of a specific node by -
using System.Xml.Linq;
XDocument xdoc = XDocument.Parse(xmlString);
List<XElement> elements = xdoc.Descendants("specificNodeName").DescendantNodes().OfType<XElement>();
If you want all XElements within the root -
List<XElement> elements = xdoc.Root.DescendantNodes().OfType<XElement>();
Doing this will also give you the "cas:Null" tag, but you can ignore it with a simple condition.
If you require to get the attributes, you can then -
foreach(XElement element in elements)
{
string attrValue = element.Attribute("attributeNameHere").Value;
}
Also, if you want all the XElement Names as a list of strings, then you can -
List<string> elementNames = xdoc.Root.DescendantNodes().OfType<XElement>().Select(x => x.Name).ToList()
This will give you a list of strings - "Black", "White", "Pink" etc.
If you want further idea on getting element names within another element or getting unique values have a look at my other post - How to get nodes from XML file without its attribute and put to a List of string
Note - you might need to manage namespace - there is plenty of help on that in SO e.g. How to parse XML with namespace
Hope this helps.
Edit
If you still want to do it in your style you'll need to create an extension method, something to this effect -
public static class MyXmlExtensions
{
public static List<XElement> GetElementsByName (this XElement main, List<string> requiredElements)
{
List<XElement> ElementsByName = new List<XElement>();
foreach(string reqElement in requiredElements)
{
List<XElement> nodes = main.Descendants(reqElement);
ElementsByName.AddRange(nodes);
}
return ElementsByName;
}
}
You can then use that -
List<string> requiredElements = new List<string> () { "group1:White", "group2:Blue", "group3:Brown" };
List<XElement> myElements = xdox.Root.GetElementsByName(requiredElements);
If you do not want to create a list and pass it, you can directly use the params keyword in your extension method - https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/params if you need help with that let me know
Upvotes: 0