Hey I have two xml files and the following Code:
DataTable table = new DataTable();
List<string> headingNames = new List<string>();
List<string> valueNames = new List<string>();
//first xml file
XDocument config = XDocument.Load(configFile);
Dictionary<string, string> dict = config.Descendants("Columns").FirstOrDefault().Elements()
.GroupBy(x => (string)x.Attribute("XPath"), y => (string)y.Attribute("Name"))
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
//second xml file
XDocument data = XDocument.Load(dataFile);
List<XElement> positions = data.Descendants("Position").ToList();
But I have to change it into XMLDocument code.
Here the first XML:
<?xml version="1.0" encoding="utf-8"?>
<ROOT>
<Columns BaseXPath="//Orders/Position/">
<Colum XPath="@PositionSK" Name="Position"/>
<Colum XPath="@PosGroup" Name="Gruppen-Nr"/>
<Colum XPath="@PosNumber" Name="PositionsNr"/>
<Colum XPath="@PositionCommercialTypeSK" Name="Status"/>
<Colum XPath="@BundlePositionSK" Name="BundlePositionSK"/>
<Colum XPath="@MainPositionSK" Name="MainPositionSK"/>
<Colum XPath="@SalesAgentPrice" Name="Preis"/>
<Colum XPath="@Catchword" Name="Suchwort"/>
<Colum XPath="@ContentComponentCommSK" Name="IKO"/>
<Colum XPath="@PositionTypeSK" Name="PositionsTyp"/>
<Colum XPath="//Advertisement[@AdvertisementSK = PositionAdvertisementRelationship/@AdvertisementSK]/@AdvertisementSK" Name="AdvertisementSK"/>
<Colum XPath="//Advertisement[@AdvertisementSK = PositionAdvertisementRelationship/@AdvertisementSK]/@AdvertisementTypeSK" Name="Formatvorgabe"/>
</Columns>
</ROOT>
I want to have all the names with the @ and the "Name": Position, Gruppen-Nr, ...
So in the Dic (from my code) is standing {[@PositionSK, Position]}, {[@PosGroup, Gruppen-Nr]}, ...
So how can I reach the same result with the XMLDocument?
In the next step I have:
foreach (XElement position in positions.Where(e => e.HasAttributes))
{
valueNames.Clear();
headingNames.Clear();
foreach (XAttribute attribute in position.Attributes().Where(a => dict.ContainsKey($"@{a.Name.LocalName}")))
{
string name = attribute.Name.LocalName;
string xName = dict["@" + name];
string value = (string)attribute;
headingNames.Add(xName);
valueNames.Add(value);
}
The output will be a DataTable at a DataGridView. It should search the Names with the @ in another xml file and find their value. But need the code with XMLDocument.. and not with linq.. can anybody help me?
A basic example of this would be:
List<string> valueNames = new List<string>();
List<string> headingNames = new List<string>();
XmlDocument doc = new XmlDocument();
doc.Load("data.xml");
for (int r = 0; r < doc.ChildNodes.Count; r++)
{
var currentNode = doc.ChildNodes.Item(r);
if (currentNode.Name.Equals("ROOT"))
{
var columnsNode = currentNode.FirstChild;
for (int i = 0; i < columnsNode.ChildNodes.Count; i++)
{
XmlNode child = columnsNode.ChildNodes.Item(i);
for (int j = 0; j < child.Attributes.Count; j++)
{
var attribute = child.Attributes.Item(j);
if (attribute.Name.Equals("XPath"))
{
headingNames.Add(attribute.Value);
}
else if (attribute.Name.Equals("Name"))
{
valueNames.Add(attribute.Value);
}
}
}
}
}
Some explanation:
Your example XML has no XML Declaration, so we can get the Root Element simply be accessing the FirstChild
property.
After Edit: Your example XML has now a XML Declaration, but the pattern is the same. For-Loop and accessing Child Elements per Indexer of this loop.
The 'Columns' Element can be reached the same way.
On the 'Columns' Element we for-loop through all Child Nodes and using the indexer (i) of our loop to get the corresponding element. Why? Because it's an XmlNodeList
Object.
With our XmlNode child
we do the same, but this time not with Child Nodes. Instead we loop through the Attribute Nodes and looking for the correct name.