How can I parse OWL file (containing RDF namespaces) with LINQ - c#

I managed to parse a simple XML file using LINQ and write it to a list box, but when I tried to get the values from the OWL file I didn't get any result by the query, so the "variables" is empty. Here is one of my attempts to do it:
XDocument owlXML = XDocument.Load(Server.MapPath("App_Data\\filename.owl"));
var variables = from variable in owlXML.Descendants("names")
where variable.Attribute("rdf:ID") != null
select new
{
type = tog.Attribute("rdf:ID").Value
};
ListBox1.DataSource = clothes;
ListBox1.DataBind();
The OWL File
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
...
...
xml:base="http://www.owl-ontologies.com/Ontology1299428518.owl">
<owl:Ontology rdf:about=""/>
<owl:Class rdf:ID="animal"/>
<owl:Class rdf:ID="natural_disaster">
<rdfs:subClassOf>
<owl:Class rdf:ID="disaster"/>
</rdfs:subClassOf>
<rdfs:subClassOf>
<owl:Class rdf:ID="natural_phenomenon"/>
</rdfs:subClassOf>
</owl:Class>
<names rdf:ID="New York"/>
<names rdf:ID="Washington"/>
<names rdf:ID="Sofia"/>
<names rdf:ID="Miami"/>
</rdf:RDF>

You have to use the appropriate namespace, rdf is not part of the attribute name, it is the namespace it is contained in - you have to declare and use the namespace - for Linq to XML that means using XNamespace - this works:
XDocument owlXML = XDocument.Load("test.xml");
XNamespace rdf = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
var variables = from variable in owlXML.Descendants("names")
where variable.Attribute(rdf +"ID") != null
select new
{
type = variable.Attribute(rdf + "ID").Value
};
Make sure that the value of the namespace in your code matches exactly how it is declared in the XML.
Also since you only have one value you are interested in you do not have to use an anonymous type here, you can simplify by returning a string directly (types then would be IEnumerable<string>):
var types = from variable in owlXML.Descendants("names")
where variable.Attribute(rdf +"ID") != null
select variable.Attribute(rdf + "ID").Value

Related

Xdocument parse file and read values

I have the below sample XML , I need to retrive the values for the following two fields txJu and ddate.I also have the code but it is giving null expection
<Doc id="580171" ddate="2019-06-21" >
<ref dtRef="2019-08-21">
<dr>
<cr>
<pj>
<pr>
<dDup txJu="0.00" txFi="0.00" txcOp="0.00" />
<comp txJu="12.96" txFi="2.45" txOp="0.00" />
</pr>
</pj>
</cr>
</dr>
</ref>
</Doc>
var xdoc = XDocument.Load(file);
string txJu = xdoc.Root.Element("comp").Attribute("txJu").Value;
string ddate = xdoc.Root.Element("Doc").Attribute("ddate").Value;
There are a couple of issues with your code. Your Root element doesn't contain comp node, Doc element is root itself, string ddate = string value = ... is invalid C# declaration.
You can modify your code per following
var compElement = xdoc.Root?.DescendantsAndSelf("comp").FirstOrDefault();
string txJu = compElement?.Attribute("txJu")?.Value;
string ddate = xdoc.Root?.Attribute("ddate")?.Value;
string value = ddate;
Use DescendantsAndSelf method to get a collection of filtered comp elements and use first of them. Access ddate attribute directly in Root element. Use null-conditional operator ? to avoid possible null reference exceptions

How to read colon in xml file using c# linq

How can I read colon in xml file using c# linq
My code in c#
XDocument xdocc = XDocument.Load(files, LoadOptions.SetLineInfo);
var mml_hi_it = xdocc.Descendants("mml:hi").Where(s => (string)s.Attribute("rend").Value == "it");
The mml literal indicates the namespace used in your xml. You should be able to find the definition in the root node. For example, based on your comment, your root tag looks like following.
<article article-type="research-article" dtd-version="1.1" xml:lang="en" xmlns:mml="w3.org/1998/Math/MathML" xmlns:xlink="w3.org/1999/xlink" xmlns:oasis="niso.org/standards/z39-96/ns/oasis-exchange/table">
In order to access Element with namespace, you need to specify the namespace using XNamespace. For example,
XNamespace mml = "w3.org/1998/Math/MathML";
var mml_hi_it = xdocc.Descendants(mml + "hi").Where(s => (string)s.Attribute("rend").Value == "it");

C# - Issues Selecting XML with Linq

I am trying to pull an event description in XML, but I am having trouble accessing the data.
I am trying to access the eventDetailsValue element.
Here is a sample of my code:
(version 1)
XElement doc = XElement.Parse(e.Result);
evtDesc = doc.Element("eventDetails").Element("eventDetails").Element("eventDetailsValue").Element("eventDetailsValue").Value;
(version2)
XElement doc = XElement.Parse(e.Result);
var xGood = from detaildoc in doc.Descendants("eventDetails")
from d in detaildoc.Elements("eventDetail").Elements("eventDetailsValue")
select d;
I have tried the following for a different element and it worked:
GeoLat = Convert.ToDouble(doc.Element("latitude").Value);
Here is a sample of the xml result (i removed the values for simplicity):
<event>
<longitude></longitude>
<latitude></latitude>
<category></category>
<dma></dma>
<activeAdvantage></activeAdvantage>
<seoUrl></seoUrl>
<assetID></assetID>
<eventID></eventID>
<eventDetailsPageUrl></eventDetailsPageUrl>
- <mediaTypes>
<mediaType></mediaType>
<mediaType></mediaType>
<mediaType></mediaType>
<mediaType></mediaType>
<mediaType></mediaType>
</mediaTypes>
<eventContactEmail />
<eventContactPhone />
<eventName></eventName>
<eventDate></eventDate>
<eventLocation></eventLocation>
<eventAddress></eventAddress>
<eventCity></eventCity>
<eventState></eventState>
<eventZip></eventZip>
<eventCountry></eventCountry>
<usatSanctioned></usatSanctioned>
<regOnline></regOnline>
<eventCloseDate></eventCloseDate>
<currencyCode></currencyCode>
<eventTypeID></eventTypeID>
<eventType></eventType>
<hasEventResults></hasEventResults>
<hasMetaResults></hasMetaResults>
<showMap></showMap>
<eventContactEmail />
<eventContactPhone />
<displayCloseDate></displayCloseDate>
<excludedFromEmailing></excludedFromEmailing>
<regOpensMessage />
<regFunnel></regFunnel>
<isValid></isValid>
<displayRegistration></displayRegistration>
- <channels>
- <channel>
<channelName></channelName>
<primaryChannel></primaryChannel>
</channel>
</channels>
- <eventDetails>
- <eventDetail>
<eventDetailsName></eventDetailsName>
<eventDetailsOrder></eventDetailsOrder>
<eventDetailsValue></eventDetailsValue>
</eventDetail>
- <eventDetail>
<eventDetailsName></eventDetailsName>
<eventDetailsOrder></eventDetailsOrder>
<eventDetailsValue></eventDetailsValue>
</eventDetail>
</eventDetails>
<eventDonationLinks />
<eventSanctions />
- <eventCategories>
- <eventCategory>
<categoryID></categoryID>
<categoryGroupCount></categoryGroupCount>
<categoryName></categoryName>
<categoryType></categoryType>
<categoryOrder></categoryOrder>
<numRegistered></numRegistered>
<maxRegistrations></maxRegistrations>
<percentFull></percentFull>
<displayDate></displayDate>
<closeDate></closeDate>
<actualCloseDate></actualCloseDate>
<isExpired></isExpired>
- <priceChanges>
- <priceChange>
<price></price>
<priceUntilDate></priceUntilDate>
</priceChange>
</priceChanges>
</eventCategory>
</eventCategories>
<eventUrl></eventUrl>
<eventContactUrl></eventContactUrl>
<eventImageUrl></eventImageUrl>
</event>
Any help would be appreciated!
The eventDetailsValue is in an array of eventDetail elements. So you need to diferentiate which element in the array you want. With this (and these LinqToXml extensions: http://searisen.com/xmllib/extensions.wiki) you can write it like this:
XElement doc = XElement.Parse(e.Result);
var details = doc.GetEnumerable("eventDetails/eventDetail", x => new
{
Name = x.Get("eventDetailsName", string.Empty),
Order = x.Get("eventDetailsOrder", string.Empty),
Value = x.Get("eventDetailsValue", string.Empty)
});
details is an IEnumerable<object> of Name's, Order's and the Value(s) you want. You can now loop through details and get the value(s) you want. I made Name, Order and Value all be strings, but by calling Get<type>("name", defaultValueByType) you can have them be other types instead.
You can loop through them like this:
foreach(var detail in details)
{
string value = detail.Value;
}
GetEnumerable is shorthand (in this case) for:
doc.Element("eventDetails").Elements("eventDetail").Select(x => new ...)
But it does null checking for you, which if your xml always produces the above xml, there would be no problems to do it long hand. And Get returns the proper value.
Note: Because this is a WindowsPhone7 project, you'll have to set a compiler flag of WindowsPhone7 so that the extensions compile without complaint (hopefully/I haven't tested it).
Try this query:
var xGood = from detaildoc in doc.Descendants("eventDetails")
select new
{
Value = detaildoc.Elements("eventDetail").Elements("eventDetailsValue").Value
};

Parsing complex XML with C#

I am trying to parse a complex XML with C#, I am using Linq to do it. Basically, I am doing a request to a server and I get XML, this is the code:
XElement xdoc = XElement.Parse(e.Result);
this.newsList.ItemsSource =
from item in xdoc.Descendants("item")
select new ArticlesItem
{
//Image = item.Element("image").Element("url").Value,
Title = item.Element("title").Value,
Description = this.Strip(item.Element("description").Value).Substring(0, 200).ToString()
}
And this is the XML structure:
<item>
<test:link_id>1282570</test:link_id>
<test:user>SLAYERTANIC</test:user>
<title>aaa</title>
<description>aaa</description>
</item>
How I can access to the property test:link_id for example?
Thanks!
Currently your XML is invalid since the test namespace is not declared, you can declare it like this:
<item xmlns:test="http://foo.bar">
<test:link_id>1282570</test:link_id>
<test:user>SLAYERTANIC</test:user>
<title>aaa</title>
<description>aaa</description>
</item>
Having this you can use XNamespace to qualify the XML element you want with the correct namespace:
XElement xdoc = XElement.Parse(e.Result);
XNamespace test = "http://foo.bar";
this.newsList.ItemsSource = from item in xdoc.Descendants("item")
select new ArticlesItem
{
LinkID = item.Element(test + "link_id").Value,
Title = item.Element("title").Value,
Description = this.Strip(item.Element("description").Value).Substring(0, 200).ToString()
}
To write a query on XML that is in a
namespace, you must use XName objects
that have the correct namespace. For
C#, the most common approach is to
initialize an XNamespace using a
string that contains the URI, then use
the addition operator overload to
combine the namespace with the local
name.
To retrieve the value of the link_id element you will need to declare and use an XML namespace for the test:link element.
Since you did not show the namespace declaration in your example XML, I am going to assume it is declared somewhere elese in the XML document. You need to locate the namespace declaration in the XML ( something like xmlns:test="http://schema.example.org" ) which is often declared in the root of the XML document.
After you know this, you can do the following to retrieve the value of the link_id element:
XElement xdoc = XElement.Parse(e.Result);
XNamespace testNamespace = "http://schema.example.org";
this.newsList.ItemsSource = from item in xdoc.Descendants("item")
select new ArticlesItem
{
Title = item.Element("title").Value,
Link = item.Element(testNamespace + "link_id").Value,
Description = this.Strip(item.Element("description").Value).Substring(0, 200).ToString()
}
See the XNamespace and Namespaces in C#, and How to: Write Queries on XML in Namespaces for further information.

Using LINQ to XML to Process XML in Multiple Namespaces

I'm trying to parse results from the YouTube API. I'm getting the results correctly as a string, but am unable to parse it correctly.
I followed suggestions on a previous thread, but am not getting any results.
My sample code is:
string response = youtubeService.GetSearchResults(search.Term, "published", 1, 50);
XDocument xDoc = XDocument.Parse(response, LoadOptions.SetLineInfo);
var list = xDoc.Descendants("entry").ToList();
var entries = from entry in xDoc.Descendants("entry")
select new
{
Id = entry.Element("id").Value,
Categories = entry.Elements("category").Select(c => c.Value)
//Published = entry.Element("published").Value,
//Title = entry.Element("title").Value,
//AuthorName = entry.Element("author").Element("name").Value,
//Thumnail = entry.Element("media:group").Elements("media:thumnail").ToList().ElementAt(0)
};
foreach (var entry in entries)
{
// entry.Id and entry.Categories available here
}
The problem is that entries has a count of 0 even though the XDocument clearly has the valid values.
The value of the response variable (Sample XML) can be seen here: http://snipt.org/lWm
(FYI: The youTube schema is listed here: http://code.google.com/apis/youtube/2.0/developers_guide_protocol_understanding_video_feeds.html)
Can anyone tell me what I'm doing wrong here?
All the data is in the "http://www.w3.org/2005/Atom" namespace; you need to use this throughout:
XNamespace ns = XNamespace.Get("http://www.w3.org/2005/Atom");
...
from entry in xDoc.Descendants(ns + "entry")
select new
{
Id = entry.Element(ns + "id").Value,
Categories = entry.Elements(ns + "category").Select(c => c.Value)
...
};
etc (untested)
When you see prefix:name, it means that name is in the namespace whose prefix has been declared as prefix. If you look at the top of the document, you'll see an xmlns:media=something. The something is the namespace used for anything with the prefix media.
This means you need to create an XNamespace for each of the namespaces you need to reference:
XNamespace media = XNamespace.Get("http://search.yahoo.com/mrss/");
and then use media for the names in that namespace:
media + "group"
The namespaces in this document are:
xmlns="http://www.w3.org/2005/Atom"
xmlns:app="http://www.w3.org/2007/app"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/"
xmlns:gd="http://schemas.google.com/g/2005"
xmlns:gml="http://www.opengis.net/gml"
xmlns:yt="http://gdata.youtube.com/schemas/2007"
xmlns:georss="http://www.georss.org/georss"
You need to set the namespace.
Creating an XName in a Namespace
As with XML, an XName can be in a namespace, or it can be in no namespace.
For C#, the recommended approach for creating an XName in a namespace is to declare the XNamespace object, then use the override of the addition operator.
http://msdn.microsoft.com/en-us/library/system.xml.linq.xname.aspx

Categories