Reputation: 23
I have the following XML sample which I need to parse in order to extract parameters:
<?xml version="1.0" encoding="UTF-8"?>
<bulkCmConfigDataFile xmlns:un="utranNrm.xsd" xmlns:xn="genericNrm.xsd" xmlns:gn="geranNrm.xsd" xmlns="configData.xsd"
xmlns:es="Vendor1SpecificAttributes.1.0.xsd">
<fileHeader fileFormatVersion="1.0" vendorName="Vendor1"/>
<configData dnPrefix="Undefined">
<xn:SubNetwork id="ONRM_ROOT_MO_R">
<xn:SubNetwork id="RNC0001">
<xn:MeContext id="BLABLA">
</xn:MeContext>
<xn:MeContext id="MACHIN">
</xn:MeContext>
<xn:MeContext id="RNC0001">
<xn:VsDataContainer id="RNC0001">
</xn:VsDataContainer>
<xn:ManagedElement id="1">
<un:RncFunction id="1">
<un:UtranCell id="111111A">
<un:attributes>
<un:uarfcnUl>9800</un:uarfcnUl>
<un:uarfcnDl>10700</un:uarfcnDl>
</un:attributes>
<xn:VsDataContainer id="111111A">
<es:Position>
<es:latitudeSign>1</es:latitudeSign>
<es:latitude>3070727</es:latitude>
<es:longitude>8786820</es:longitude>
</es:Position>
</xn:VsDataContainer>
<xn:VsDataContainer id="1">
</xn:VsDataContainer>
</un:UtranCell>
<un:UtranCell id="111111B">
<un:attributes>
<un:uarfcnUl>9800</un:uarfcnUl>
<un:uarfcnDl>10700</un:uarfcnDl>
</un:attributes>
<xn:VsDataContainer id="111111B">
<es:Position>
<es:latitudeSign>1</es:latitudeSign>
<es:latitude>3070555</es:latitude>
<es:longitude>8786666</es:longitude>
</es:Position>
</xn:VsDataContainer>
<xn:VsDataContainer id="1">
</xn:VsDataContainer>
</un:UtranCell>
</un:RncFunction>
</xn:ManagedElement>
</xn:MeContext>
</xn:SubNetwork>
</xn:SubNetwork>
</configData>
<fileFooter dateTime="2011-11-28T08:38:45Z"/>
</bulkCmConfigDataFile>
So far I've only been able to retrieve the first element by name for a given namespace:
XNamespace xn = "genericNrm.xsd";
XNamespace un = "utranNrm.xsd";
var test1 = xmldoc.Descendants(xn + "MeContext").FirstOrDefault();
which will only give me the first Element "MeContext" (in this example this will return the MeContext with id=BLABLA).
If I try the following instead
XNamespace xn = "genericNrm.xsd";
XNamespace un = "utranNrm.xsd";
var test1 = xmldoc.Descendants(xn + "MeContext");
test1 will be null ...
1 - My first question is how do I retrieve a specific element using its "id" attribute (in this specific example I'm looking for the id="RNC0001"). I tried many things coming from stackoverflow including the following:
XNamespace xn = "genericNrm.xsd";
IEnumerable<XElement> utrancells =
xmldoc.Root
.Elements(xn + "MeContext")
.Where(el => (string)el.Attribute("id") == "RNC0001");
which only returns null values.
2 - The second problem is how to retrieve a collection of elements from the <xn:MeContext id="RNC0001"></xn:MeContext>
?
I would like to get all the <un:UtranCell id="XXXXX"></un:UtranCell>
(and content) in a collection so I can extract data from each of them (each represent a different entity). For instance I need to retrieve
<es:latitude>3070555</es:latitude>
<es:longitude>8786666</es:longitude>
from each <un:UtranCell id="XXXXX"></un:UtranCell>
For this I tried (as a test):
XNamespace un = "utranNrm.xsd";
var test3 = xmldoc.Elements(un + "UtranCell");
var test4 = test1.Elements(un + "UtranCell");
and again it returns only null values ...
Edit for Daniel: The real code is:
public void parseFile()
{
XNamespace xn = "genericNrm.xsd";
XNamespace un = "utranNrm.xsd";
XNamespace cd = "configData.xsd";
var test1 = xmldoc.Descendants(xn + "MeContext").FirstOrDefault();
var test1bis = xmldoc.Descendants(xn + "MeContext");
}
This gives me:
test1 = <xn:MeContext id="BLABLA" xmlns:xn="genericNrm.xsd"></xn:MeContext>
test1bis = {System.Xml.Linq.XContainer.GetDescendants} | name = null
Upvotes: 2
Views: 362
Reputation: 838266
The problem in both cases is that you are using Elements
instead of Descendants
. The difference is that Elements
only returns those elements that are immediate children - i.e. one level deep, whereas Descendants
searches the entire subtree. Try this instead:
IEnumerable<XElement> utrancells =
xmldoc.Root
.Descendants(xn + "MeContext")
.Where(el => (string)el.Attribute("id") == "RNC0001");
Upvotes: 1