I am new to xml and unable to find a way to get content in between tags.
My XML file is
<?xml version="1.0" encoding="utf-8"?>
<block1>
<file name="c:\w0.xml">
<word>Text</word>
<number>67</number>
</file>
<file name="c:\w1.xml">
<word>Text</word>
<number>67</number>
</file>
<file name="c:\w2.xml">
<word>Text</word>
<number>67</number>
</file>
</block1>
LINQ to XML is a great place to start. Consider the following code to parse your XML.
string xml = #"<?xml version=""1.0"" encoding=""utf-8""?>
<block1>
<file name=""c:\w0.xml"">
<word>Text</word>
<number>67</number>
</file>
<file name=""c:\w1.xml"">
<word>Text</word>
<number>67</number>
</file>
<file name=""c:\w2.xml"">
<word>Text</word>
<number>67</number>
</file>
</block1>";
XDocument document = XDocument.Parse(xml);
var block = from file in document.Descendants("file")
select new
{
Name = file.Attribute ("name").Value,
Word = file.Element("word").Value,
Number = (int)file.Element("number")
};
foreach (var file in block)
{
Console.WriteLine("{0}\t{1}\t{2}", file.Name, file.Word, file.Number );
}
You can, of course, load the XML directly from a file using XDocument.Load instead of using Parse to read an XML string. XDocument is in the System.Xml.Linq namespace. Frankly, I would start there, but there are other options to work with XML in the System.Xml namespace (XmlReader.Create, etc.).
You need to use an XML Query language. I would recommend LINQ to XML if you're using .Net 3.5 or XPath if you're using something earlier. XPath has the advantage of being an industry standard, but LINQ to XML is a much 'cleaner' API, in my opinion.
How to query XML with an XPath expression by using Visual C# - Tutorial on using XPath
LINQ to XML Video Tutorial
MSDN XPath Examples - From the XPath Reference
Location Paths - Includes text() function for example.
Related
I have xml files which look like this:
<?xml version="1.0" encoding="utf-8"?>
<record id="177" restricted="false">
<type>record type</type>
<startdate>2000-10-10</startdate>
<enddate>2014-02-01</enddate>
<titles>
<title xml:lang="en" type="main">Main title</title>
<!-- only one title element with type main -->
<title xml:lang="de" type="official">German title</title>
<!-- can have more titles of type official -->
</titles>
<description>description of the record</description>
<categories>
<category id="122">
<name>category name</name>
<description>category description</description>
</category>
<!-- can have more categories -->
</categories>
<tags>
<tag id="5434">
<name>tag name</name>
<description>tag description</description>
</tag>
<!-- can have more tags -->
</tags>
</record>
How do I select the data from these xml files using LINQ, or should I use something else?
You can load xml into XDocument objects using either the Load() method
for files, or the Parse() method for strings:
var doc = XDocument.Load("your-file.xml");
// OR
var doc = XDocument.Parse(yourXmlString);
Then you can access the data using LINQ:
var titles =
from title in doc.XPathSelectElements("//title")
where title.Attribute("type").Value == "official"
select title.Value;
Was searching for examples of Xmlserializer and found this: How to Deserialize XML document
So why not to try. I did Ctrl+C and Edit -> Paste Special -> Paste XML As Classes in Visual Studio 2013 and... Whoa I got all the classes generated. One condition target framework must be 4.5 and this function is available from Visual Studio 2012+ (as stated in that post)
I have an XML file as follows. I would like to extract the Version number from this file.
I tried XML parsing. But, that is for node values only. I am able to get this file as string as follows. var doc = XDocument.Load("WMAppManifest.xml");
<?xml version="1.0" encoding="utf-8"?>
<Deployment xmlns="http://schemas.microsoft.com/windowsphone/2012/deployment" AppPlatformVersion="8.0">
<DefaultLanguage xmlns="" code="en-US" />
<App xmlns="" ProductID="{a3f55b1e-c183-4645-9b19-87a41a206978}" Title="sometitle" RuntimeType="Silverlight" Version="1.0.0.0" Genre="apps.normal" Author="M-Files author" BitsPerPixel="32" Description="Apache Cordova for Windows Phone" Publisher="CordovaExample" PublisherID="{b93a0d8e-5aa9-4d9b-b232-17e2d852e779}">
<IconPath IsRelative="true" IsResource="false">ApplicationIcon.png</IconPath>
</App>
</Deployment>
You can access the XML declaration node as follows:
XmlDeclaration declaration = doc.ChildNodes
.OfType<XmlDeclaration>()
.FirstOrDefault();
You can then read the value of declaration.Version.
Or, if you are after the 'app' version attribute in the XML document itself, try the following
string version = doc.Descendants("App")
.Single()
.Attribute("Version").Value
In machine.config file there are elements written there by 3rd party software so it looks like this:
<configuration>
<configSections>
...
</configSections>
...
<Custom>
<Level1> ...
</Level1>
<Level2> ...
</Level2>
<Level3>
<add key="key_text1" value="s1" />
<add key="key_text2" value="s2" />
<add key="key_text3" value="s3" />
</Level3>
</Custom>
</configuration>
I want to get e.g. a value ("s2") of "value" attribute where key="key_text2" from configuration/Custom/Level3 node. So far, I tried to open machine.config as an XML and work from there:
Configuration config = ConfigurationManager.OpenMachineConfiguration();
XmlDocument doc = new XmlDocument();
doc.LoadXml(config.FilePath);
however, I get XmlException "Data at the root level is invalid.". I also don't know how to use Configuration class methods directly to get this done. Any ideas would be appreciated.
Use RuntimeEnvironment.SystemConfigurationFile to get machine.config location:
XmlDocument doc = new XmlDocument();
doc.Load(RuntimeEnvironment.SystemConfigurationFile);
Also why not to use Linq to Xml?
XDocument xdoc = XDocument.Load(RuntimeEnvironment.SystemConfigurationFile);
var element = xdoc.XPathSelectElement("//Custom/Level3/add[#value='s2']");
if (element != null)
key = (string)element.Attribute("key");
Try using the Load() method instead of LoadXml()
doc.Load(config.FilePath);
I also sould suggest you have a look at XDocument instead of XmlDocument. LINQ will really be of use when getting that value from the config file.
For a xml Document like below I display all subfolders and files for the currently selected folder. For that from the xml string i remove the unmatched folders and built a UI using XSLT on the front end. Seems the operation is removing all the nodes that makes resulting string invalid xml. so
How do i remove elements from xml using Linq to Xml without changing the validity of the document
Xml Document
<?xml version="1.0" encoding="utf-8"?>
<Folder>
<Folders>
<Folder ID="1" Name="Root" ParentId="0">
<Files></Files>
</Folder>
<Folder ID="2" Name="My Documents" ParentId="1">
<Files>
<File Name="LicenceCode.txt" Size="2000" CreatedOn="1/1/2012 12:12:00 PM" CreatedBy="1" ModifiedOn="1/10/2012 10:12:56 AM" ModifiedBy="2"></File>
</Files>
</Folder>
</Folders>
</Folder>
Code
XElement filesAndFolders = XElement.Parse(xmlDocumentString);
string outputFolders = string.concat(from folders in filesAndFolders in filesAndFolder.Elements("Folder").Folder("Folders") where folders.Attribute("ParentId").Value.Equals(selectedFolderId) select folders);
//pass outputFolders string to xsl to build the UI
Problem
The outputFolders string is invalid as it contains only below string not a valid document
<Folder ID="2" Name="My Documents" ParentId="1">
<Files>
<File Name="LicenceCode.txt" Size="2000" CreatedOn="1/1/2012 12:12:00 PM" CreatedBy="1" ModifiedOn="1/10/2012 10:12:56 AM" ModifiedBy="2"></File>
</Files>
</Folder>
How about removing the elements you don't want:
var doc = XDocument.Parse(xmlString);
doc.Element("Folder").Element("Folders").Elements("Folder").Where(f => f.Attribute("ID").Value == "1").Remove();
I have built two XML files that map the content of a given folder:
<root>
<folder name="C:\a\b" permision="yes" folderCount="1">
<folders>
<folder name="C:\a\b\c" permision="yes" folderCount="1">
<folders>
<folder name="C:\a\b\c\e" permision="yes" folderCount="0">
<folders/>
<files>
<file name="401-1.htm"/>
<file name="401-2.htm"/>
<file name="401-3.htm"/>
</files>
</folder>
<folder name="C:\a\b\d" permision="yes" folderCount="0">
<folders/>
<files>
<file name="401-4.htm"/>
<file name="401-5.htm"/>
<file name="401-3.htm"/>
</files>
</folder>
</folders>
<files/>
</folder>
</root>
I'd like to know if there is a way to find the difference between the files.
(One file is the old state and the second is the new state, and it's only possible to add files and not remove them. It would be great to remove identical nodes from the new state so only the new files will be left).
I would use LINQ to XML like the project below:
Diff in XML files with LINQ:
http://www.codeproject.com/KB/linq/LinqDiff.aspx
If you'd like to do it in code, you could use Microsoft'ss XML Diff and Patch GUI Tool, and although there isn't a great deal of documentation, there is enough that you should be able to easily diff two XML files in code, in a fairly short space of time. I use it in a couple of projects as part of a series of unit tests which ensure that XML files are being generated correctly.
If you just want to view the differences between the two files, then you could just use any decent diff tool.