Loop through each file in directory and write output to text - c#

I have around 15,000 XML files in a folder, an example of a XML filename is; 000010000.img.xml
Each XML file contains specific information I need in a single text file.
Each XML file has the exact same structure aside from the information presented.
Here is what I want to focus in on (within the XML file)
<imgdir name="000010000.img">
<imgdir name="info">
<int name="version" value="10" />
<int name="cloud" value="0" />
<int name="town" value="0" />
<float name="mobRate" value="1.0" />
<string name="bgm" value="Bgm34/MapleLeaf" />
<int name="returnMap" value="10000" />
<string name="mapDesc" value="" />
<int name="hideMinimap" value="0" />
<int name="forcedReturn" value="999999999" />
<int name="moveLimit" value="0" />
<string name="mapMark" value="MushroomVillage" />
<int name="swim" value="0" />
<int name="fieldLimit" value="8260" />
<int name="VRTop" value="-892" />
<int name="VRLeft" value="-1064" />
<int name="VRBottom" value="915" />
<int name="VRRight" value="1334" />
<int name="fly" value="0" />
<int name="noMapCmd" value="0" />
<string name="onFirstUserEnter" value="" />
<string name="onUserEnter" value="go10000" />
<int name="standAlone" value="0" />
<int name="partyStandAlone" value="0" />
<string name="fieldScript" value="" />
</imgdir>
</imgdir>
<imgdir name="portal">
<imgdir name="0">
<string name="pn" value="sp" />
<int name="pt" value="0" />
<int name="x" value="-389" />
<int name="y" value="183" />
<int name="tm" value="999999999" />
<string name="tn" value="" />
</imgdir>
<imgdir name="1">
<string name="pn" value="sp" />
<int name="pt" value="0" />
<int name="x" value="-416" />
<int name="y" value="185" />
<int name="tm" value="999999999" />
<string name="tn" value="" />
</imgdir>
<imgdir name="2">
<string name="pn" value="sp" />
<int name="pt" value="0" />
<int name="x" value="-450" />
<int name="y" value="183" />
<int name="tm" value="999999999" />
<string name="tn" value="" />
</imgdir>
<imgdir name="3">
<string name="pn" value="out00" />
<int name="pt" value="2" />
<int name="x" value="1080" />
<int name="y" value="541" />
<int name="tm" value="20000" />
<string name="tn" value="in00" />
<string name="script" value="" />
<int name="hideTooltip" value="0" />
<int name="onlyOnce" value="0" />
<int name="delay" value="0" />
</imgdir>
</imgdir>
A batch file does not work; as you can see in my other thread: Batch script not working?
I need a C# application to open each XML file, grab specific information (that I will specify below), write that information into a single text file, and rinse and repeat till every XML file has been read.
Using the XML file snippet/actual XML file information posted above, here is how I need the text file text structure to be;
[10000]
total=4
sp 0 -389 183 999999999
sp 0 -416 185 999999999
sp 0 -450 183 999999999
out00 2 1080 541 20000
I just cannot wrap my head around on how to do this in a c# console application.
I am asking for help, anything is appreciated!

string[] files = Directory.GetFiles(#"SomeWhere");
List<string> result = new List<string>();
foreach (string file in files)
{
string[] lines = File.ReadAllLines(file);
// Grab information from the lines and store it in result
// by using result.Add(...) or result.AddRange(...)
}
File.WriteAllLines(#"AlsoSomewhere", result);

Here is a quick and dirty program I wrote up. I had to add a root to your XML file for it to play nice-nice with the program. I hope this helps!
Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace ConsoleApp5 {
public class Program {
public static void Main(string[] args) {
string test = getValuesOneFile("xmltest.xml");
Console.WriteLine(test);
Console.ReadLine();
}
public static string getValuesOneFile(string fileName) {
string finalString = "";
XElement xmlDocument = XElement.Load((fileName));
XElement infoImgDir = GetImgDir(xmlDocument, "info");
finalString += "[" + GetInt(infoImgDir, "returnMap") + "]\n";
finalString += "total=" + GetChildrenCount(GetImgDir(xmlDocument,"portal")) + "\n";
IEnumerable<XElement> portals = GetImgDir(xmlDocument, "portal").Elements();
foreach (XElement currentPortal in portals) {
finalString += GetString(currentPortal, "pn") + " ";
finalString += GetInt(currentPortal, "pt") + " ";
finalString += GetInt(currentPortal, "x") + " ";
finalString += GetInt(currentPortal, "y") + " ";
finalString += GetInt(currentPortal, "tm") + "\n";
}
return finalString;
}
public static XElement GetImgDir(XElement file, string imgDirName) {
return file.Descendants("imgdir").FirstOrDefault(x => (string)x.Attribute("name") == imgDirName);
}
public static int GetInt(XElement data, string attribName) {
var element = data.Descendants("int").FirstOrDefault(x => (string)x.Attribute("name") == attribName);
if (element == null)
return 0;
var value = (int?)element.Attribute("value");
if (value == null)
return 0;
return value.Value;
}
public static string GetString(XElement data, string attribName) {
var element = data.Descendants("string").FirstOrDefault(x => (string)x.Attribute("name") == attribName);
if (element == null)
return "";
var value = (string)element.Attribute("value");
if (value == null)
return "";
return value;
}
public static int GetChildrenCount(XElement data) {
return data.Elements().Count();
}
}
}

Related

Extracting XML data reverse XSLT?

I have some XML data that resides in an XML file and I am trying to get it into datatables. I have tried putting it into a Dataset. I have tried putting it in XML nodes. However, it all seems random and just all over the place and it's not working. I have tried to include a summarized version of how the data looks below. How can I extract it into clear tables and rows and columns? Also, I am not sure if this would help or not, but this XML is created from 4 tables that are then extracted to an XML file using and XSLT file. Is there a way to do it in REVERSE to take the XSLT and XML file into the original datatables?
<obj name="TableName0">
<int name="ANumberThatsAColumn1" val="" />
<int name="ANumberThatsAColumn2" val="" />
<int name="ANumberThatsAColumn3" val="" />
<str name="ADateThatsAColumn4" val="2022-12-16T08:43:07.9870485-06:00" />
</obj>
<list name="TableName1">
<obj href="RowOfData1/">
<int name="ColName1" val="0" />
<str name="ColName2" val="1" />
<int name="ColName3" val="1" />
<int name="ColName4" val="0" />
<int name="ColName5" val="6" />
<int name="ColName6" val="0" />
<str name="ColName7" val="#3062" />
<ref name="ColName8" href="SomeValue1" />
</obj>
<obj href="RowOfData2/">
<int name="ColName1" val="0" />
<str name="ColName2" val="1" />
<int name="ColName3" val="1" />
<int name="ColName4" val="0" />
<int name="ColName5" val="6" />
<int name="ColName6" val="0" />
<str name="ColName7" val="#2543" />
<ref name="ColName8" href="SomeValue2" />
<int name="ColName9" val="0" />
<int name="ColName10" val="0" />
<int name="ColName11" val="0" />
</obj>
</list>
<list name="TableName2">
<list name="row1">
<int name="R0" val="0" displayName="#7925" />
<int name="R1" val="1" displayName="#7926" />
</list>
<list name="row2">
<int name="R0" val="0" displayName="#21641" />
<int name="R1" val="1" displayName="#21642" />
<int name="R2" val="2" displayName="#21643" />
</list>
</list>
Here is a conceptual example for you.
XML shredding is happening in T-SQL via two XQuery methods:
.node()
.value()
XQuery Language Reference (SQL Server)
SQL
DECLARE #xml XML =
N'<root>
<obj name="TableName0">
<int name="ANumberThatsAColumn1" val=""/>
<int name="ANumberThatsAColumn2" val=""/>
<int name="ANumberThatsAColumn3" val=""/>
<str name="ADateThatsAColumn4" val="2022-12-16T08:43:07.9870485-06:00"/>
</obj>
<list name="TableName1">
<obj href="RowOfData1/">
<int name="ColName1" val="0"/>
<str name="ColName2" val="1"/>
<int name="ColName3" val="1"/>
<int name="ColName4" val="0"/>
<int name="ColName5" val="6"/>
<int name="ColName6" val="0"/>
<str name="ColName7" val="#3062"/>
<ref name="ColName8" href="SomeValue1"/>
</obj>
<obj href="RowOfData2/">
<int name="ColName1" val="0"/>
<str name="ColName2" val="1"/>
<int name="ColName3" val="1"/>
<int name="ColName4" val="0"/>
<int name="ColName5" val="6"/>
<int name="ColName6" val="0"/>
<str name="ColName7" val="#2543"/>
<ref name="ColName8" href="SomeValue2"/>
<int name="ColName9" val="0"/>
<int name="ColName10" val="0"/>
<int name="ColName11" val="0"/>
</obj>
</list>
<list name="TableName2">
<list name="row1">
<int name="R0" val="0" displayName="#7925"/>
<int name="R1" val="1" displayName="#7926"/>
</list>
<list name="row2">
<int name="R0" val="0" displayName="#21641"/>
<int name="R1" val="1" displayName="#21642"/>
<int name="R2" val="2" displayName="#21643"/>
</list>
</list>
</root>';
-- INSRT INTO <targetTable>
SELECT c.value('#name', 'VARCHAR(20)') AS name
, c.value('#val', 'INT') AS val
, c.value('#displayName', 'VARCHAR(20)') AS displayName
FROM #xml.nodes('/root/list[#name="TableName2"]/list/int') AS t(c);
-- INSRT INTO <targetTable>
SELECT c.value('#name', 'VARCHAR(20)') AS name
, c.value('#val', 'VARCHAR(20)') AS val
, c.value('#href', 'VARCHAR(20)') AS href
FROM #xml.nodes('/root/list[#name="TableName1"]/obj/*') AS t(c);

Im trying to make a small program in c# console that reads some parts of the xml file but im getting a error

The error i get is Daya at the root level is invalid. Line 1, position 1.
using System;
using System.Xml;
using System.IO;
namespace XmlReaderConsoleAPP
{
class Program
{
static void Main()
{
XmlDocument xml = new XmlDocument();
xml.LoadXml("c:\\SaintGobain_Pam_20210118.xml");
string _byteOrderMarkUtf8 =
Enconding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (xml.StartWith(_byteOrderMarkUtf8))
{
var lastIndexOfUtf8 = _byteOrderMarkUtf8.Length - 1;
xml = xml.Remove(0, _byteOrderMarkUtf8.Length - 1);
}
XmlNodeList xnLista = xml.SelectNodes("/Batches/Batch/BatchFields/BatchField/Documents/Document/IndexFields/IndexField/Pages/Page");
foreach(XmlNode xn in xnLista)
{
string formulario = xn["FormTypeName"].InnerText;
string Value = xn["Value"].InnerText;
string FileName = xn["ImportFileName"].InnerText;
Console.WriteLine("Formulário: {0}", formulario, "Value: {1} ", Value, "FilePath: {2}", FileName);
}
}
}
}
And the XML contents are
<ImportSession>
<Batches>
<Batch Name="MSG_SaintGobainPam_20210118" Description="SaintGobain_20210118"
BatchClassName="SAINTGOBAIN - Faturas Notas" Processed="1">
<BatchFields>
<BatchField Name="CAPALOTE" Value="0" />
<BatchField Name="NCONTENTOR" Value="0" />
</BatchFields>
<Documents>
<Document FormTypeName="DOC_SaintGobain_Faturas_Notas">
<IndexFields>
<IndexField Name="ETIQUETA" Value="ZE80047804" />
</IndexFields>
<Pages>
<Page
ImportFileName="\\umm\c$\acxmlaid\SaintGobain\20210118\ZE80047804.pdf" />
</Pages>
</Document>
<Document FormTypeName="DOC_SaintGobain_Faturas_Notas">
<IndexFields>
<IndexField Name="ETIQUETA" Value="ZE80047842" />
</IndexFields>
<Pages>
<Page
ImportFileName="\\umm\c$\acxmlaid\SaintGobain\20210118\ZE80047842.pdf" />
</Pages>
</Document>
<Document FormTypeName="DOC_SaintGobain_Faturas_Notas">
<IndexFields>
<IndexField Name="ETIQUETA" Value="ZE80047843" />
</IndexFields>
<Pages>
<Page
ImportFileName="\\umm\c$\acxmlaid\SaintGobain\20210118\ZE80047843.pdf" />
</Pages>
</Document>
<Document FormTypeName="DOC_SaintGobain_Faturas_Notas">
<IndexFields>
<IndexField Name="ETIQUETA" Value="ZE80047849" />
</IndexFields>
<Pages>
<Page
ImportFileName="\\umm\c$\acxmlaid\SaintGobain\20210118\ZE80047849.pdf"/>
</Pages>
</Document>
<Document FormTypeName="DOC_SaintGobain_Faturas_Notas">
<IndexFields>
<IndexField Name="ETIQUETA" Value="ZE80047853" />
</IndexFields>
<Pages>
<Page
ImportFileName="\\umm\c$\acxmlaid\SaintGobain\20210118\ZE80047853.pdf" />
</Pages>
</Document>
<Document FormTypeName="DOC_SaintGobain_Faturas_Notas">
<IndexFields>
<IndexField Name="ETIQUETA" Value="ZE80047854" />
</IndexFields>
<Pages>
<Page
ImportFileName="\\umm\c$\acxmlaid\SaintGobain\20210118\ZE80047854.pdf" />
</Pages>
</Document>
<Document FormTypeName="DOC_SaintGobain_Faturas_Notas">
<IndexFields>
<IndexField Name="ETIQUETA" Value="ZE80047855" />
</IndexFields>
<Pages>
<Page
ImportFileName="\\umm\c$\acxmlaid\SaintGobain\20210118\ZE80047855.pdf" />
</Pages>
</Document>
<Document FormTypeName="DOC_SaintGobain_Faturas_Notas">
<IndexFields>
<IndexField Name="ETIQUETA" Value="ZE80047860" />
</IndexFields>
<Pages>
<Page
ImportFileName="\\umm\c$\acxmlaid\SaintGobain\20210118\ZE80047860.pdf"/>
ErrorCode="20" ErrorMessage="Illegal file format
(\\umm\c$\acxmlaid\SaintGobain\20210118\ZE80047860.pdf)" />
</Pages>
</Document>
<Document FormTypeName="DOC_SaintGobain_Faturas_Notas">
<IndexFields>
<IndexField Name="ETIQUETA" Value="ZE80047861" />
</IndexFields>
<Pages>
<Page
ImportFileName="\\umm\c$\acxmlaid\SaintGobain\20210118\ZE80047861.pdf"/>
</Pages>
</Document>
</Documents>
</Batch>
Im asking this because i couldnt find a answer to my question but if there is please link it in the answers.
XML FILE is now added to the post as you can see.
I really dont know why it keeps happening but ye hope you guys can help.
Some suggestions to move forward:
static void Main()
{
XmlDocument xml = new XmlDocument();
// Catch Exception, print message and bail out.
try{
// vv "LoadXml" replaced by "Load"
xml.Load("c:\\SaintGobain_Pam_20210118.xml");
}
catch(Exception ex)
{
Console.WriteLine("OOps: {0}", ex.Message);
return;
}
string _byteOrderMarkUtf8 =
Enconding.UTF8.GetString(Encoding.UTF8.GetPreamble());
if (xml.StartWith(_byteOrderMarkUtf8))
{
var lastIndexOfUtf8 = _byteOrderMarkUtf8.Length - 1;
xml = xml.Remove(0, _byteOrderMarkUtf8.Length - 1);
}
// vv replace XPath expression
XmlNodeList xnLista = xml.SelectNodes(#"//Pages/Page");
foreach(XmlNode xn in xnLista)
{
string formulario = xn["FormTypeName"].InnerText;
string Value = xn["Value"].InnerText;
string FileName = xn["ImportFileName"].InnerText;
// Correct syntax:
Console.WriteLine("Formulário: {0}, Value: {1} ,FilePath: {2}",formulario, Value, FileName);
}
}
Then manually sanitize (for now) the source file:
Delete ErrorCode="20" ErrorMessage="Illegal file format (\\umm\c$\acxmlaid\SaintGobain\20210118\ZE80047860.pdf)" />
And give it another try.

Using C#, how can we pull attribute values from an XML Schema file and output that onto a CSV file?

I am trying to pull the attribute values for each of the element, that is in this XMl Schema file(XML below). I want the attribute values for the following: type, label, CompTypes, readonly, hidden, and required.
For example, here is one of the elements in the XML file:
<element type="xpowercomponent_FeaturedTiles" UID="40204fc9b5424b349e03134d777d29bc" label="Featured Tiles" readonly="false" hidden="false" default="" required="false" Component="" CompTypes="ThemedTileSetComponent;ThemedTileSetElectedComponent;" AutoEmbed="" WrappedUp="" AllowWrappingChange="" />
The expected result for this element should be:
xpowercomponent_FeaturedTiles, Featured Tiles, ThemedTileSetComponent,
ThemedTileSetElectedComponent, readonly="false", hidden="false",
required="false"
I have started a C# app to get this information, however it is not getting all the information properly. Could you please take a look at the code, and see how this can be fixed or improved? Is there a better way of approaching this, maybe LINQ? The ultimate goal is to then output these attribute values/data in a CSV file.
C#
class Program
{
static void Main(string[] args)
{
Parse();
}
public static void Parse()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"D:\New Text Document.xml");
var captureElements = new List<CustomElements>();
var xdocument = xmlDoc.ToXDocument();
foreach (var element in xdocument.Elements())
{
foreach (var node in element.Elements()) //childs...
{
if (node.Name.LocalName.Equals("ElementType"))
{
foreach (var scopeNode in node.Elements())
{
if (scopeNode.Name.LocalName.Equals("element"))
{
var xml = XElement.Parse(scopeNode.ToString());
var customElement = new CustomElements();
customElement.Type = xml.Attribute("type")?.Value;
customElement.Label = xml.Attribute("label")?.Value;
customElement.CompTypes = xml.Attribute("CompTypes")?.Value;
customElement.Readonly = xml.Attribute("readonly")?.Value;
customElement.Hidden = xml.Attribute("hidden")?.Value;
customElement.Require = xml.Attribute("required")?.Value;
captureElements.Add(customElement);
}
}
}
}
}
}
}
public static class DocumentExtensions
{
public static XmlDocument ToXmlDocument(this XDocument xDocument)
{
var xmlDocument = new XmlDocument();
using (var xmlReader = xDocument.CreateReader())
{
xmlDocument.Load(xmlReader);
}
return xmlDocument;
}
public static XDocument ToXDocument(this XmlDocument xmlDocument)
{
using (var nodeReader = new XmlNodeReader(xmlDocument))
{
nodeReader.MoveToContent();
return XDocument.Load(nodeReader);
}
}
}
public class CustomElements
{
public string Type { get; set; }
public string Label { get; set; }
public string CompTypes { get; set; }
public string Readonly { get; set; }
public string Hidden { get; set; }
public string Require { get; set; }
}
Full XML Schema file:
<Schema xmlns:dt="urn:schemas-microsoft-com:datatypes" name="TopTier" xmlns="urn:schemas-microsoft-com:xml-data">
<AttributeType name="ID" dt:type="id" required="yes" />
<AttributeType name="Name" dt:type="string" required="yes" />
<AttributeType name="UniqueID" dt:type="int" default="schemas/107" />
<AttributeType name="Icon" dt:type="int" default="2" />
<AttributeType name="FriendlyName" dt:type="string" default="Top Tier" />
<AttributeType name="SS" dt:type="boolean" default="true" />
<AttributeType name="DSS" dt:type="boolean" default="true" />
<AttributeType name="ViewName" dt:type="" default="" />
<AttributeType name="DefaultCategorization" dt:type="string" default="" />
<AttributeType name="Version" dt:type="int" default="9" />
<ElementType name="Exports" content="textOnly" />
<ElementType name="Title" dt:type="string" content="textOnly" />
<ElementType name="Excerpt" dt:type="string" content="textOnly">
<description>This info is used to display on pages that link to this page.</description>
</ElementType>
<ElementType name="ThumbnailImage" dt:type="imagefile" content="textOnly">
<description>Thumbnail dimension should be 75 x 75 pixels.</description>
</ElementType>
<ElementType name="xhtml_BodyCopy" content="textOnly" />
<ElementType name="xpowerlist_LeftSidebarComponentsOverride" content="eltOnly" />
<ElementType name="xpowercomponent_LeftSidebarComponent" content="eltOnly" />
<ElementType name="xpowercomponent_FeaturedTiles" content="eltOnly" />
<ElementType name="SecondaryTitle" dt:type="string" content="textOnly" />
<ElementType name="xpowerlist_SecondaryComponentList" content="eltOnly" />
<ElementType name="xpowercomponent_SecondaryItem" content="eltOnly" />
<ElementType name="xpowergroupstart_SEOGroup" content="eltOnly">
<description>Search Engine Optimization Group</description>
</ElementType>
<ElementType name="BrowserTitle" dt:type="string" content="textOnly" />
<ElementType name="MetaDescription" dt:type="string" content="textOnly" />
<ElementType name="NoIndex" dt:type="boolean" content="textOnly" />
<ElementType name="NoFollow" dt:type="boolean" content="textOnly" />
<ElementType name="NoODP" dt:type="boolean" content="textOnly" />
<ElementType name="Priority" dt:type="enumeration" values="0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0" content="textOnly" />
<ElementType name="PublishDate" dt:type="localdate" content="textOnly" />
<ElementType name="xpowergroupend_" content="eltOnly" />
<ElementType name="xpowernavigation_BreadcrumbNavigation" content="eltOnly" />
<ElementType name="xpowercomponent_SectionControl" content="eltOnly" />
<ElementType name="TopTier" content="eltOnly" order="seq">
<attribute type="ID" />
<attribute type="Name" />
<element type="Title" UID="2bbcb2816ba743e2bd935d526f47d688" label="Title" readonly="false" hidden="false" default="" required="true" />
<element type="Excerpt" UID="2ac3ade7d9c34cae8a7f304d9754db86" label="Excerpt" readonly="false" hidden="false" default="" required="true" />
<element type="ThumbnailImage" UID="f4940dbfe27f4783a97c356f3ba0f959" label="Thumbnail Image" readonly="false" hidden="false" default="" required="false" Expanded="false" Width="" Height="" Border="" HSpace="" VSpace="" Alignment="" AlternateText="" />
<element type="xhtml_BodyCopy" UID="055d4709ffb24402a14f9d13af417401" label="Body Copy" readonly="false" hidden="false" default="" required="false" Height="" />
<element type="xpowerlist_LeftSidebarComponentsOverride" UID="1d281fa780b6419089c52913640ade93" label="Left Sidebar Components Override" readonly="false" hidden="false" default="" required="false" Enclosed="" AllowEnclosureChange="" List="xpowercomponent_LeftSidebarComponent" Component="" CompTypes="" AutoEmbed="" WrappedUp="" AllowWrappingChange="" />
<element type="xpowercomponent_FeaturedTiles" UID="40204fc9b5424b349e03134d777d29bc" label="Featured Tiles" readonly="false" hidden="false" default="" required="false" Component="" CompTypes="ThemedTileSetComponent;ThemedTileSetElectedComponent;" AutoEmbed="" WrappedUp="" AllowWrappingChange="" />
<element type="SecondaryTitle" UID="3d00fbe341ff4f2481c6199deb046997" label="Secondary Title" readonly="false" hidden="false" default="" required="false" />
<element type="xpowerlist_SecondaryComponentList" UID="3bc6293a826a4f2081dca1c5e1415978" label="Secondary Component List" readonly="false" hidden="false" default="" required="false" Enclosed="" AllowEnclosureChange="" List="xpowercomponent_SecondaryItem" Component="" CompTypes="TaxonomyTileComponent;ServiceComponent;ContactComponent;TitledCollection" AutoEmbed="" WrappedUp="" AllowWrappingChange="" />
<element type="xpowergroupstart_SEOGroup" UID="bf312bbd47d74c758d13695b8fa011c0" label="SEO Group" readonly="false" hidden="true" default="" required="false" Enclosed="" AllowEnclosureChange="" />
<element type="BrowserTitle" UID="c777f36e6f094b50a04692d3bfef387e" label="Browser Title" readonly="false" hidden="false" default="" required="false" />
<element type="MetaDescription" UID="05bab416415541beb05e90b94f7e5248" label="Meta Description" readonly="false" hidden="false" default="" required="false" />
<element type="NoIndex" UID="e224c1a3aaa846d9b19579d59d9b1af7" label="No Index" readonly="false" hidden="false" default="" required="false" />
<element type="NoFollow" UID="b40ae068c0d749c4bb8ecd589388bb1b" label="No Follow" readonly="false" hidden="false" default="" required="false" />
<element type="NoODP" UID="2557027d711d41c3b3ccbd3aab4650dd" label="No ODP" readonly="false" hidden="false" default="" required="false" />
<element type="Priority" UID="f49eec4e94864e03aedbd0e2be6a2822" label="Priority" readonly="false" hidden="false" default="" required="false" values="0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0" />
<element type="PublishDate" UID="5fdba65915744addb710631476822112" label="Publish Date" readonly="true" hidden="true" default="" required="false" />
<element type="xpowergroupend_" />
<element type="xpowernavigation_BreadcrumbNavigation" UID="140b1582e50e4a098e190942980bd728" label="Breadcrumb Navigation" readonly="false" hidden="true" default="" required="true" Expanded="false" Navigation="Ancestors" GenerationOrder="down" StartPage="x5" MaxNodes="" MaxDepth="" Query="">
<element type="Exports" default="" />
</element>
<element type="xpowercomponent_SectionControl" UID="56564fa9c2bd4e9ba44a417960146376" label="SectionControl" readonly="false" hidden="true" default="" required="true" Component="" CompTypes="SectionControl" AutoEmbed="" WrappedUp="" AllowWrappingChange="" />
</ElementType>
</Schema>
you can use System.Xml.Linq to get all the elements and the required attributes as below
XDocument document = XDocument.Load(#"D:\New Text Document.xml");
var eleCollection = document.Elements("element");
foreach (var element in eleCollection)
{
var type = element.Attribute("Type").Value;
}
This is easiest way one can use for loops on nodes to get the information in each node.
use node.ChildNodes property to get the chilenodes.
XmlDocument doc = new XmlDocument();
doc.Load("filepath");
//Here Path could be- "//ElementType" ---> this will give all nodes with name ElementType
XmlNodeList nodes= doc.SelectNodes("//give path of nodes you want attributes for");
foreach (XmlNode node in nodes)
{
//Assuming you want information of element tags
foreach (XmlNode child in node.ChildNodes)
{
string name= node.Attributes["type"].Value;
string name= node.Attributes["label"].Value;
}
}

How can I select all subnodes of a node, and not all descendats?

I've got the following XML:
<...>
<...>
<tabular>
<time from="2014-05-22T10:00:00" to="2014-05-22T12:00:00" period="1">
<symbol number="3" numberEx="3" var="03d" />
<precipitation value="0" />
<windDirection deg="191.8" code="SSW" />
<windSpeed mps="1.3" />
<temperature unit="celsius" value="16" />
<pressure unit="hPa" value="1010.6" />
</time>
<time from="2014-05-22T10:00:00" to="2014-05-22T12:00:00" period="1">
<symbol number="3" numberEx="3" var="03d" />
<precipitation value="0" />
<windDirection deg="191.8" code="SSW" />
<windSpeed mps="1.3" />
<temperature unit="celsius" value="16" />
<pressure unit="hPa" value="1010.6" />
</time>
<time from="2014-05-22T10:00:00" to="2014-05-22T12:00:00" period="1">
<symbol number="3" numberEx="3" var="03d" />
<precipitation value="0" />
<windDirection deg="191.8" code="SSW" />
<windSpeed mps="1.3" />
<temperature unit="celsius" value="16" />
<pressure unit="hPa" value="1010.6" />
</time>
I've managed with LINQ to get the tabular list:
var tabular = doc.Root.Descendants("tabular").ToList();
tabular count is now 1. What I want is a list of children of tabular. I've tried the extra descendant:
var tabular = doc.Root.Descendants("tabular").Descendants().ToList();
But that return a list of every descendant of tabular, resulting in a list where time, symbol, precipitation and so on is in the list. How can I get a list where the list contains time nodes of tabular?
I want a list of all time nodes, so I can serialize it to a object and access the values
Use Elements instead of Descendants if you want to get only direct children of tabular
var tabular = doc.Root.Descendants("tabular").Elements().ToList();
UPDATE: Hints for parsing time elements into objects
var times =
from t in xdoc.Descendants("tabular").Elements()
let symbol = t.Element("symbol")
let temperature = t.Element("temperature")
select new
{
From = (DateTime)t.Attribute("from"),
To = (DateTime)t.Attribute("to"),
Period = (int)t.Attribute("period"),
Symbol = new
{
Number = (int)symbol.Attribute("number"),
NumberEx = (int)symbol.Attribute("numberEx"),
Var = (string)symbol.Attribute("var")
},
Precipitation = (int)t.Element("precipitation").Attribute("value"),
WindSpeed = (double)t.Element("windSpeed").Attribute("mps"),
Temperature = new
{
Unit = (string)temperature.Attribute("unit"),
Value = (string)temperature.Attribute("value")
}
};
Output:
[
{
From: "2014-05-22T10:00:00",
To: "2014-05-22T12:00:00",
Period: 1,
Symbol: { Number: 3, NumberEx: 3, Var: "03d" },
Precipitation: 0,
WindSpeed: 1.3,
Temperature: { Unit: "celsius", Value: "16" }
},
// ...
]

select value of attribute by linq to xml

in my xml file how i can select the value for attributes TagId in ServiceAssignment elements by linq to xml
Note : this xml in a String Property not in xml file
<AnchoredXml xmlns="urn:schema:Microsoft.Rtc.Management.ScopeFramework.2008" SchemaWriteVersion="1">
<Key ScopeClass="Global">
<SchemaId Namespace="urn:schema:Microsoft.Rtc.Management.Settings.ServiceAssignment.2008" ElementName="ServiceAssignments" />
<AuthorityId Class="Host" InstanceId="00000000-0000-0000-0000-000000000000" />
</Key>
<Dictionary Count="1">
<Item>
<Key />
<Value Signature="2ffb6b0d-0239-4016-b08b-40520d1687ff">
<ServiceAssignments xmlns="urn:schema:Microsoft.Rtc.Management.Settings.ServiceAssignment.2008">
<ServiceAssignment TagId="659550892">
<Component Name="Registrar">
<ServiceId xmlns="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008" SiteId="1" RoleName="Registrar" Instance="1" />
</Component>
<Component Name="PresenceFocus">
<ServiceId xmlns="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008" SiteId="1" RoleName="UserServices" Instance="1" />
</Component>
</ServiceAssignment>
<ServiceAssignment TagId="911048693">
<Component Name="Registrar">
<ServiceId xmlns="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008" SiteId="1" RoleName="Registrar" Instance="2" />
</Component>
<Component Name="PresenceFocus">
<ServiceId xmlns="urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008" SiteId="1" RoleName="UserServices" Instance="2" />
</Component>
</ServiceAssignment>
</ServiceAssignments>
</Value>
</Item>
</Dictionary>
</AnchoredXml>
i try this code but give me a null exception
var MyList = doc.Root.Elements("ServiceAssignment").Select(c=>c.Attribute(("TagId")).Value).ToList();
You have namespaced elements in the document so you need to include them in your queries.
XNamespace itemNs = "urn:schema:Microsoft.Rtc.Management.ScopeFramework.2008";
XNamespace assignmentNs = "urn:schema:Microsoft.Rtc.Management.Settings.ServiceAssignment.2008";
var query =
from item in doc.Descendants(itemNs + "Item")
from assignment in item.Descendants(assignmentNs + "ServiceAssignment")
select (long)assignment.Attribute("TagId");
string xmlString =
#"<AnchoredXml xmlns='urn:schema:Microsoft.Rtc.Management.ScopeFramework.2008' SchemaWriteVersion='1'>
<Key ScopeClass='Global'>
<SchemaId Namespace='urn:schema:Microsoft.Rtc.Management.Settings.ServiceAssignment.2008' ElementName='ServiceAssignments' />
<AuthorityId Class='Host' InstanceId='00000000-0000-0000-0000-000000000000' />
</Key>
<Dictionary Count='1'>
<Item>
<Key />
<Value Signature='2ffb6b0d-0239-4016-b08b-40520d1687ff'>
<ServiceAssignments xmlns='urn:schema:Microsoft.Rtc.Management.Settings.ServiceAssignment.2008'>
<ServiceAssignment TagId='659550892'>
<Component Name='Registrar'>
<ServiceId xmlns='urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008' SiteId='1' RoleName='Registrar' Instance='1' />
</Component>
<Component Name='PresenceFocus'>
<ServiceId xmlns='urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008' SiteId='1' RoleName='UserServices' Instance='1' />
</Component>
</ServiceAssignment>
<ServiceAssignment TagId='911048693'>
<Component Name='Registrar'>
<ServiceId xmlns='urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008' SiteId='1' RoleName='Registrar' Instance='2' />
</Component>
<Component Name='PresenceFocus'>
<ServiceId xmlns='urn:schema:Microsoft.Rtc.Management.Deploy.Topology.2008' SiteId='1' RoleName='UserServices' Instance='2' />
</Component>
</ServiceAssignment>
</ServiceAssignments>
</Value>
</Item>
</Dictionary>
</AnchoredXml>";
var doc = XDocument.Parse(xmlString);
var TagIds = doc.Descendants()
.Elements()
.Where(e =>
e.HasAttributes &&
e.Name.LocalName.Equals("ServiceAssignment") &&
e.Attribute("TagId") != null)
.Select(e => e.Attribute("TagId").Value);
Your XML contains namespaces, so you can't just compare the full name.
If you don't care about the namespaces, you can use XName.LocalName:
var result = from element in doc.Root.Descendants()
where element.Name.LocalName == "ServiceAssignment"
select (int)element.Attribute("TagId");
You can try with this code
var result = from item in XElement.Load("YourFile.xml").Root.Elements("ServiceAssignment")
where item.Attribute("TagId") == value
select item ;

Categories