I have a xml file that looks like this:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetAllArticlesResponse xmlns="http://www.borger.dk/2009/WSArticleExport/v1">
<GetAllArticlesResult xmlns:a="http://www.borger.dk/2009/WSArticleExport/v1/types" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:ArticleDescription>Test 1</a:ArticleDescription>
<a:ArticleDescription>Test 2</a:ArticleDescription>
</GetAllArticlesResult>
</GetAllArticlesResponse>
</s:Body>
</s:Envelope>
I'm trying to get all the articles, but can't get it to work.
XDocument doc = XDocument.Parse(soapResult);
IEnumerable<XElement> articles = doc.Root.Descendants("a:ArticleDescription");
This has work before, but because the element name as a : then it fails..
Any idea how to fix this.
Thanks for all the inputs.
I ended with::
XNamespace a = "http://www.borger.dk/2009/WSArticleExport/v1/types";
XDocument doc = XDocument.Parse(soapResult);
IEnumerable<XElement> articles = doc.Root.Descendants(a + "ArticleDescription");
List<Article> article = articles.Select(m => new Article()
{
ArticleID = m.Element(a + "ArticleID").Value.ToString(),
ArticleTitle = m.Element(a + "ArticleTitle").Value.ToString(),
ArticleUrl = m.Element(a + "ArticleUrl").Value.ToString(),
LastUpdated = m.Element(a + "LastUpdated").Value.ToString(),
PublishingDate = m.Element(a + "PublishingDate").Value.ToString()
}).ToList();
json = JsonConvert.SerializeObject(article);
Here's an alterante way:
var doc = XDocument.Load(xml);
XNamespace ns1 = "http://schemas.xmlsoap.org/soap/envelope/";
XNamespace ns2 = "http://www.borger.dk/2009/WSArticleExport/v1";
XNamespace ns3 = "http://www.borger.dk/2009/WSArticleExport/v1/types";
var result = doc.Element(ns1 + "Envelope")
.Element(ns1 + "Body")
.Element(ns2 + "GetAllArticlesResponse")
.Element(ns2 + "GetAllArticlesResult")
.Elements(ns3 + "ArticleDescription")
.Select(x => x.Value);
Or
var doc = XDocument.Load(xml);
var envelope = doc.Root;
var body = (XElement)envelope.FirstNode;
var getAllArticlesResponse = (XElement)body.FirstNode;
var getAllArticlesResult = (XElement)getAllArticlesResponse.FirstNode;
var articleDescriptions = getAllArticlesResult.Nodes().Cast<XElement>();
var result = articleDescriptions.Select(x => x.Value);
Here is easiest way using Xml Linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication137
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
string[] description = doc.Descendants().Where(x => x.Name.LocalName == "ArticleDescription").Select(x => (string)x).ToArray();
}
}
}
The prefix a: is a short-for of the namespace name "http://www.borger.dk/2009/WSArticleExport/v1/types", you can see that where the prefix is declared.
You can use namespace-aware XName's when querying:
var descriptions = doc.Root.Descendants(
XName.Get("ArticleDescription", "http://www.borger.dk/2009/WSArticleExport/v1/types"));
Of course you could store the namespaces you want in variables, you don't have to type them out every time.
You can also just look at the local names, if you're not worried about collisions.
var descriptions = doc.Root.Descendants().Where(x => x.Name.LocalName == "ArticleDescription");
Related
I have the following XML and i want to convert the contents to something along the lines of the following format.
PatientId: 123455, IdScheme: Test ....
<?xml version="1.0"?>
<gls:TheDocument xmlns:pbr="http://www.something.com"
xmlns:gls="http://www.testsomething.com"
xmlns:cnr="http://www.organisation.com"
xmlns:h="http://www.w3.org/1999/xhtml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" schemaVersion="2.8">
<gls:PatientDem>
<cnr:PatientId>
<cnr:IdValue>123455</cnr:IdValue>
<cnr:IdScheme>TEST</cnr:IdScheme>
<cnr:IdType>PRN</cnr:IdType>
</cnr:PatientId>
<cnr:PatientName>
<cnr:Name>
<cnr:Title>Mr</cnr:Title>
<cnr:GivenName>Joe</cnr:GivenName>
<cnr:FamilyName>Wood</cnr:FamilyName>
</cnr:Name>
<cnr:NameType>Current Name</cnr:NameType>
</cnr:PatientName>
<cnr:PatientAddress>
<cnr:Address>
<cnr:AddressLine>57 High Street</cnr:AddressLine>
<cnr:AddressLine>London</cnr:AddressLine>
</cnr:Address>
<cnr:PostCode>WC1E 7HU</cnr:PostCode>
<cnr:AddressType>Current Residence</cnr:AddressType>
</cnr:PatientAddress>
<cnr:DateOfBirth>1969-11-02</cnr:DateOfBirth>
<cnr:Sex>M</cnr:Sex>
</gls:PatientDem>
<pbr:PatientAdminRef>
<pbr:Referrer>
<pbr:RefGP>
<cnr:GpcpName>
<cnr:FullName>DR SMITH</cnr:FullName>
</cnr:GpcpName>
<cnr:TheOrganisation>
<cnr:OrganisationId>
<cnr:IdValue>52522</cnr:IdValue>
<cnr:IdScheme>PracticeID</cnr:IdScheme>
<cnr:IdType>Healthcare Organisation</cnr:IdType>
</cnr:OrganisationId>
<cnr:OrganisationName>National Health
Service</cnr:OrganisationName>
<cnr:OrganisationAddress>
<cnr:TheAddress>
<cnr:AddressLine1>Centre House</cnr:AddressLine1>
<cnr:AddressLine2>799 Chichester
Street</cnr:AddressLine2>
<cnr:AddressLine3>London</cnr:AddressLine3>
</cnr:TheAddress>
<cnr:AddressType>Practice Address</cnr:AddressType>
</cnr:OrganisationAddress>
<cnr:OrganisationTelecom>
<cnr:TelephoneNumber>016190542350</cnr:TelephoneNumber>
<cnr:TeleType>Voice</cnr:TeleType>
</cnr:OrganisationTelecom>
</cnr:TheOrganisation>
</pbr:RefGP>
</pbr:Referrer>
</pbr:PatientAdminRef>
</gls:TheDocument>
So is it possible to do this? I had a go at doing this but I know for a fact i am doing it wrong as it cannot produce the result i want so any help will be much appreciated:
C# Code
XDocument doc = XDocument.Parse(xml);
XElement root = doc.Root;
XNamespace glsNs = root.GetNamespaceOfPrefix("gls");
XNamespace cnrNS = root.GetNamespaceOfPrefix("cnr");
XNamespace pbrNS = root.GetNamespaceOfPrefix("pbr");
var output = new StringBuilder();
foreach (var result in doc.Descendants(gls + "PatientDem").Select(x => new {
Key = (string)x.Name.LocalName,
Value = x.Value
}))
{
output.AppendLine($"{result.key} : {result.value}");
}
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication108
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement root = doc.Root;
XNamespace cnrNs = root.GetNamespaceOfPrefix("cnr");
var results = doc.Descendants(cnrNs + "PatientId").Select(x => new {
value = (string)x.Element(cnrNs + "IdValue"),
scheme = (string)x.Element(cnrNs + "IdScheme")
}).ToList();
}
}
}
I have the following XML
<User
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/GaryLeaderboardsAPI.Models">
<Game_ID>3</Game_ID>
<UserGUID>e00d3560-4133-4ba6-8bba-e6c8659468b4</UserGUID>
<UserName>tony2</UserName>
<User_ID>16</User_ID>
</User>
Using C# I am loading this into an XMLDocument, How do I retrieve the UserGUID value?
Leveraging System.Xml.Linq you could do
string xml = "..."; // your inline XML
var doc = System.Xml.Linq.XDocument.Parse(xml);
or
string xmlFile = "..."; // your XML filename
var doc = System.Xml.Linq.XDocument.Load(xmlFile);
and then, to get the UserGUID
var userGuid = doc.Descendants().Where(x=>x.Name.LocalName == "UserGUID").First().Value;
This will work for you.
string xml = "<User xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://schemas.datacontract.org/2004/07/GaryLeaderboardsAPI.Models\">" +
"<Game_ID>3</Game_ID>" +
"<UserGUID>e00d3560-4133-4ba6-8bba-e6c8659468b4</UserGUID>" +
"<UserName>tony2</UserName>" +
"<User_ID>16</User_ID>" +
"</User>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
var id = doc.GetElementsByTagName("UserGUID")[0].InnerText;
You need to use the namespace. I often use mipnw approach (probably stole idea from one of my postings). See code below :
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 = #"\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement user = doc.Root;
XNamespace ns = user.GetDefaultNamespace();
string UserGUID = (string)user.Element(ns + "UserGUID");
}
}
}
I'm trying to create a program having the following steps:
1) Get all xml files from a user given path
2) Open each of the files (if any) and search for nodes <institution> where it is in the format <funding-source><institution-wrap><institution>...</institution></institution-wrap></funding-source>
3) Get the value of the nodes <institution> and search the exact value in the database xml inside the nodes <skosxl:literalForm xml:lang="...">
4) If found, get the attribute value of its parent node <skos:Concept rdf:about="..."> minus the string http://dx.doi.org/
5) Add a node <institution-id institution-id-type="fundref"> in the xml file after the <institution> node with the value like <funding-source><institution-wrap><institution>...</institution><institution-id institution-id-type="fundref">VALUE of the rdf:about attribute</institution-id></institution-wrap></funding-source>
Here is a sample input file and the desired output for that file.
What I have tried:
string pathToUpdatedFile = #"D:\test\Jobs";
var files=Directory.GetFiles(pathToUpdatedFile,"*.xml");
foreach (var file in files)
{
var fundingDoc = XDocument.Load(#"D:\test\database.xml");
XNamespace rdf=XNamespace.Get("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
XNamespace skosxl = XNamespace.Get("http://www.w3.org/2008/05/skos-xl#");
XNamespace skos=XNamespace.Get("http://www.w3.org/2004/02/skos/core#");
var targetAtt = fundingDoc.Descendants(skos+"Concept").Elements(skosxl+"prefLabel")
.ToLookup(s => (string)s.Element(skosxl+"literalForm"), s => (string)s.Parent.Attribute(rdf+"about"));
XDocument outDoc = XDocument.Parse(File.ReadAllText(file),LoadOptions.PreserveWhitespace);
foreach (var f in outDoc.Descendants("funding-source").Elements("institution-wrap"))
{
if (f.Element("institution-id") == null)
{
var name = (string)f.Element("institution");
var x = targetAtt[name].FirstOrDefault(); // just take the first one
if (x != null)
f.Add(new XElement("institution-id", new XAttribute("institution-id-type","fundref"),x.Substring(#"http://dx.doi.org/".Length)));
}
outDoc.Save(file);
}
Console.ReadLine();
But it is not working...Can somebody help...
See code below :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Data;
using System.Data.OleDb;
namespace ConsoleApplication31
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
const string DATABASE = #"c:\temp\test1.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement article = doc.Root;
XNamespace ns = article.GetDefaultNamespace();
XDocument docDatabase = XDocument.Load(DATABASE);
XElement rdf = docDatabase.Root;
XNamespace nsSkosxl = rdf.GetNamespaceOfPrefix("skosxl");
XNamespace nsRdf = rdf.GetNamespaceOfPrefix("rdf");
List<XElement> prefLabels = rdf.Descendants(nsSkosxl + "prefLabel").ToList();
Dictionary<string, List<string>> dictLabels = prefLabels.GroupBy(x => (string)x.Descendants(nsSkosxl + "literalForm").FirstOrDefault(), y => (string)y.Element(nsSkosxl + "Label").Attribute(nsRdf + "about"))
.ToDictionary(x => x.Key, y => y.ToList());
List<XElement> fundingSources = article.Descendants(ns + "funding-source").ToList();
foreach (XElement fundingSource in fundingSources)
{
XElement institutionWrap = fundingSource.Element(ns + "institution-wrap");
string institution = (string)fundingSource;
if (dictLabels.ContainsKey(institution))
{
institutionWrap.Add(new XElement("institution-id", new object[] {
new XAttribute("institution-id-type","fundref"),
dictLabels[institution]
}));
}
else
{
Console.WriteLine("Dictionary doesn't contain : '{0}'", institution);
}
}
Console.ReadLine();
}
}
}
I think this is what you are looking for (MODIFIED jdweng's CODE A LITTLE)
const string FILENAME = #"c:\temp\test.xml";
const string DATABASE = #"c:\temp\test1.xml";
public static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement article = doc.Root;
XNamespace ns = article.GetDefaultNamespace();
XDocument docDatabase = XDocument.Load(DATABASE);
XElement rdf = docDatabase.Root;
XNamespace nsSkosxl = rdf.GetNamespaceOfPrefix("skosxl");
XNamespace nsSkos = rdf.GetNamespaceOfPrefix("skos");
XNamespace nsRdf = rdf.GetNamespaceOfPrefix("rdf");
List<XElement> prefLabels = rdf.Descendants(nsSkos + "Concept").ToList();
Dictionary<string, List<string>> dictLabels = prefLabels.GroupBy(x => (string)x.Descendants(nsSkosxl + "literalForm").FirstOrDefault(), y => (string)y.Parent.Element(nsSkos+"Concept").Attribute(nsRdf + "about").Value.Substring(18))
.ToDictionary(x => x.Key, y => y.ToList());
List<XElement> fundingSources = article.Descendants(ns + "funding-source").ToList();
foreach (XElement fundingSource in fundingSources)
{
XElement institutionWrap = fundingSource.Element(ns + "institution-wrap");
string institution = (string)fundingSource;
if (dictLabels.ContainsKey(institution))
{
institutionWrap.Add(new XElement("institution-id", new object[] {
new XAttribute("institution-id-type","fundref"),
dictLabels[institution]
}));
}
}
doc.Save(FILENAME);
Console.WriteLine("Done");
Console.ReadLine();
}
I have the following XML:
<resource>
<description>TTT</description>
<title>TEST</title>
<entity xmlns="TdmBLRuPlUz.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="TdmBLRuPlUz.xsd TdmBLRuPlUz.xsd">
<UzdProd>
<row>
<F_DAUDZ>50</F_DAUDZ>
<BR_DAUDZ/>
<DAUDZ>50</DAUDZ>
<U_DAUDZ/>
<NKODS>ST2.0_014_023</NKODS>
</row>
</UzdProd>
<UzdMat>
<row>
<NKODS>SAG 2.0_014_150</NKODS>
<NNOSAUK>Sagatave 2.0mm*0.14*150m</NNOSAUK>
<PK_VIEN>1</PK_VIEN>
<DAUDZ>0.077</DAUDZ>
<F_DAUDZ>0.077</F_DAUDZ>
</row>
</UzdMat>
</entity>
</resource>
And this is my C# code:
XNamespace ns = "TdmBLRuPlUz.xsd";
XDocument doc = XDocument.Parse(xml);
foreach (XElement element in doc.Descendants(ns + "row"))
{
Console.WriteLine(element.Element(ns + "NKODS").Value);
string NKODS = element.Element(ns + "NKODS").Value;
string F_DAUDZ = element.Element(ns + "F_DAUDZ").Value;
string DAUDZ = element.Element(ns + "DAUDZ").Value;
}
What I need is to read values from the XML nodes NKODS, F_DAUDZ and DAUDZ.
The problem is that there are repeating nodes with those names and with this code it gives me the last ones which are under UzdMat node. What would be the way to get the values for these nodes under UzdProd?
I tried to change row to UzdProd, but that didn't work.
You need to read the specific row you want rather than looping through all of them. For example:
var prodRow = doc.Descendants(ns + "UzdProd").Elements(ns + "row").Single();
var matRow = doc.Descendants(ns + "UzdMat").Elements(ns + "row").Single();
var prodNkods = (string) prodRow.Element(ns + "NKODS");
var matNkods = (string) matRow.Element(ns + "NKODS");
See this fiddle for a working demo.
See if this works :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication25
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement entity = doc.Descendants().Where(x => x.Name.LocalName == "entity").FirstOrDefault();
XNamespace ns = entity.GetDefaultNamespace();
var results = entity.Elements().Select(x => new {
uzd = x.Name.LocalName,
dict = x.Descendants(ns + "row").Elements().GroupBy(y => y.Name.LocalName, z => (string)z)
.ToDictionary(y => y.Key, z => z.FirstOrDefault())
}).ToList();
}
}
}
I have an xml file with attribute
xmlns="http://www.reservwire.com/namespace/WebServices/Xml">
When I remove this attribute, then I can read each tag. If I don't remove attribute I receive error message "Object refrence not set to instance of object"
My C# code:
XmlDocument xml = new XmlDocument();
xml.Load(Server.MapPath("~/HotelSearchCriteria/PrepareBooking.xml"));
string CommmitLevel = xml.DocumentElement
.SelectSingleNode("/BookingCreate/CommitLevel")
.InnerText;
My XML:
<BookingCreate xmlns="http://www.reservwire.com/namespace/WebServices/Xml">
<Authority>
<Org>danco</Org>
<User>xmltest</User>
<Password>xmltest</Password>
<Language>en</Language>
<Currency>EUR</Currency>
<TestDebug>false</TestDebug>
<Version>1.26</Version>
</Authority>
<QuoteId>17081233-3</QuoteId>
<HotelStayDetails>
<Room>
<Guests>
<Adult title="Mr" first="djkvb" last="jkj" />
<Adult title="Mr" first="jfs" last="kjdjs" />
</Guests>
</Room>
</HotelStayDetails>
<HotelSearchCriteria>
<AvailabilityStatus>allocation</AvailabilityStatus>
<DetailLevel>basic</DetailLevel>
</HotelSearchCriteria>
<CommitLevel>prepare</CommitLevel>
</BookingCreate>
What to do to read xml with xmlns attribute? It is necessary for me to have xmlns attribute.
You need to specify the namespace, by using a namespace manager. This should work
XmlDocument bookingXml = new XmlDocument();
bookingXml.Load("PrepareBooking.xml");
XmlNamespaceManager ns = new XmlNamespaceManager(bookingXml.NameTable);
ns.AddNamespace("booking", "http://www.reservwire.com/namespace/WebServices/Xml");
var commitLevel = bookingXml.SelectSingleNode("//booking:BookingCreate//booking:CommitLevel", ns).InnerText;
Using 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);
XElement bookingCreate = doc.Descendants().Where(x => x.Name.LocalName == "BookingCreate").FirstOrDefault();
XNamespace ns = bookingCreate.GetDefaultNamespace();
var results = doc.Descendants(ns + "BookingCreate").Select(x => new {
org = (string)x.Descendants(ns + "Org").FirstOrDefault(),
user = (string)x.Descendants(ns + "User").FirstOrDefault(),
password = (string)x.Descendants(ns + "Password").FirstOrDefault(),
language = (string)x.Descendants(ns + "Language").FirstOrDefault(),
currency = (string)x.Descendants(ns + "Currency").FirstOrDefault(),
testDebug = (Boolean)x.Descendants(ns + "TestDebug").FirstOrDefault(),
version = (string)x.Descendants(ns + "Version").FirstOrDefault(),
quoteId = (string)x.Element(ns + "QuoteId"),
guests = x.Descendants(ns + "Adult").Select(y => new {
title = (string)y.Attribute("title"),
first = (string)y.Attribute("first"),
last = (string)y.Attribute("last")
}).ToList(),
availability = (string)x.Descendants(ns + "AvailabilityStatus").FirstOrDefault(),
detailLevel = (string)x.Descendants(ns + "DetailLevel").FirstOrDefault()
}).FirstOrDefault();
}
}
}