locked
correspondence among XML elements RRS feed

  • Question

  •  

    Hello all,

    I have an XML file which includes many <osgb:cartographicMember> elements which also include some elements such as descriptingGroup, orientation, coordinates and so on.. I would like to receive some specific values of all the cartographicMember if all of them exist in it.

     

    The problem lies in the fact that not all the cartographicMember elements contain all the specific elements that i am intrested in. So, when i do e.g. the following :

     

    XmlNodeList theme = xDoc.GetElementsByTagName("osgb:theme");

    XmlNodeList descGroup = xDoc.GetElementsByTagName("osgbBig SmileescriptiveGroup");

     

    i get two NodeLists with different length and therefore i cannot identify which theme goes with which descripiveGroup and which element (cartographicMember) does not have both of them (or the ones that i am intrested in)..

     

    Is there a way, with a native function to preserve the XML original structure and be able to obtain the values of the elements which have all X attributes that i am intrested in?

     

    many thanks!

    Monday, December 3, 2007 1:50 AM

Answers

  • Use XPath and SelectNodes to first select the cartographicMember elements, then use relative XPath expressions and SelectNodes again to select the child elements (or descendant elements) you are interested in.

    If you need more help then show us the relevant XML.

    Code could follow this approach:

    Code Block

    XmlDocument xDoc = new XmlDocument();

    xDoc.Load(@"file.xml");

    XmlNamespaceManager nsmgr = new XmlNamespaceManager(xDoc.NameTable);

    nsmgr.AddNamespace("osgb", "namespaceURIgoesHere");

    foreach (XmlElement member in xDoc.SelectNodes("//osgb:cartographicMember", nsmgr))

    {

      XmlNodeList themes = member.SelectNodes(".//osgb:theme", nsmgr);

      XmlNodeList groups = member.SelectNodes(".//osgb:descriptiveGroup", msmgr);

      // now you can process the descendant themes and groups of each member element her

    }

     

     

    Monday, December 3, 2007 2:19 PM
  • What exactly is it that you want to achieve? Your first post talked about theme and descriptiveGroup elements and not all cartographicMember elements having those children but in the sample you posted, as far as I can see, all cartographicMember elements have those children. You can use code like this:

    Code Block

                XmlDocument xDoc = new XmlDocument();

                xDoc.Load(@"..\..\XMLFile1.xml");

                XmlNamespaceManager nsmgr = new XmlNamespaceManager(xDoc.NameTable);

                nsmgr.AddNamespace("osgb", "http://www.ordnancesurvey.co.uk/xml/namespaces/osgb");

                foreach (XmlElement member in xDoc.SelectNodes("//osgb:cartographicMember", nsmgr))
                {

                    XmlElement theme = member.SelectSingleNode(".//osgb:theme", nsmgr) as XmlElement;
                    if (theme != null)
                    {
                        Console.WriteLine("theme is {0}.", theme.InnerText);
                    }

                    XmlElement group = member.SelectSingleNode(".//osgb:descriptiveGroup", nsmgr) as XmlElement;

                    if (group != null)
                    {
                        Console.WriteLine("group is {0}.", group.InnerText);
                    }

                }

     

     

    That prints out the theme and group InnerText for those cartographicMember elements having such descendants.
    Monday, December 10, 2007 5:30 PM

All replies

  • Use XPath and SelectNodes to first select the cartographicMember elements, then use relative XPath expressions and SelectNodes again to select the child elements (or descendant elements) you are interested in.

    If you need more help then show us the relevant XML.

    Code could follow this approach:

    Code Block

    XmlDocument xDoc = new XmlDocument();

    xDoc.Load(@"file.xml");

    XmlNamespaceManager nsmgr = new XmlNamespaceManager(xDoc.NameTable);

    nsmgr.AddNamespace("osgb", "namespaceURIgoesHere");

    foreach (XmlElement member in xDoc.SelectNodes("//osgb:cartographicMember", nsmgr))

    {

      XmlNodeList themes = member.SelectNodes(".//osgb:theme", nsmgr);

      XmlNodeList groups = member.SelectNodes(".//osgb:descriptiveGroup", msmgr);

      // now you can process the descendant themes and groups of each member element her

    }

     

     

    Monday, December 3, 2007 2:19 PM
  • Hello Martin and many thanks for your reply,

    I would be very glad if you could be more specific, taking into acount the following part of the XML file

    Code Block

     > 

      <?xml version="1.0" encoding="UTF-8" ?>
    <!--
     Data generated by EDINA Digimap, University of Edinburgh for lan@6ec96e01:00005ac on Thu Nov 15 21:34:34 GMT 2007. 
      -->
    <!--
    Created by GO Publisher WFS v1_2_5b Build 317 from 2007/06/25 10:58
      -->
    <!--
    Snowflake Software Ltd. (http://www.snowflakesoftware.co.uk)
      -->
    - <osgb:FeatureCollection xmlns:osgb="http://www.ordnancesurvey.co.uk/xml/namespaces/osgb" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.ordnancesurvey.co.uk/xml/namespaces/osgb http://www.ordnancesurvey.co.uk/xml/schema/v4/OSDNFFeatures.xsd">
    - <gml:boundedBy>
      <gml:null>unknown</gml:null>
      </gml:boundedBy>
      <osgb:queryTime>2007-11-15T21:39:45</osgb:queryTime>
    - <osgb:cartographicMember>
    - <osgb:CartographicSymbol fid="osgb1000001137059216">
      <osgb:featureCode>10082</osgb:featureCode>
      <osgb:version>1</osgb:version>
      <osgb:versionDate>2001-11-08</osgb:versionDate>
      <osgb:theme>Water</osgb:theme>
    - <osgb:changeHistory>
      <osgb:changeDate>1970-01-01</osgb:changeDate>
      <osgb:reasonForChange>New</osgb:reasonForChange>
      </osgb:changeHistory>
      <osgb:descriptiveGroup>Inland Water</osgb:descriptiveGroup>
      <osgb:descriptiveTerm>Direction Of Flow</osgb:descriptiveTerm>
      <osgb:orientation>2250</osgb:orientation>
      <osgb:physicalLevel>50</osgb:physicalLevel>
      <osgb:physicalPresence>Indicator</osgb:physicalPresence>
    - <osgb:point>
    - <gml:Point srsName="osgb:BNG">
      <gml:coordinates>318264.0,515127.5</gml:coordinates>
      </gml:Point>
      </osgb:point>
      </osgb:CartographicSymbol>
      </osgb:cartographicMember>
    - <osgb:cartographicMember>
    - <osgb:CartographicSymbol fid="osgb1000001137059351">
      <osgb:featureCode>10082</osgb:featureCode>
      <osgb:version>1</osgb:version>
      <osgb:versionDate>2001-11-08</osgb:versionDate>
      <osgb:theme>Water</osgb:theme>
    - <osgb:changeHistory>
      <osgb:changeDate>1970-01-01</osgb:changeDate>
      <osgb:reasonForChange>New</osgb:reasonForChange>
      </osgb:changeHistory>
      <osgb:descriptiveGroup>Inland Water</osgb:descriptiveGroup>
      <osgb:descriptiveTerm>Direction Of Flow</osgb:descriptiveTerm>
      <osgb:orientation>2378</osgb:orientation>
      <osgb:physicalLevel>50</osgb:physicalLevel>
      <osgb:physicalPresence>Indicator</osgb:physicalPresence>
    - <osgb:point>
    - <gml:Point srsName="osgb:BNG">
      <gml:coordinates>318273.0,515163.5</gml:coordinates>
      </gml:Point>
      </osgb:point>
      </osgb:CartographicSymbol>
      </osgb:cartographicMember>
    - <osgb:cartographicMember>
    - <osgb:CartographicSymbol fid="osgb1000001137059332">
      <osgb:featureCode>10082</osgb:featureCode>
      <osgb:version>1</osgb:version>
      <osgb:versionDate>2001-11-08</osgb:versionDate>
      <osgb:theme>Water</osgb:theme>
    - <osgb:changeHistory>
      <osgb:changeDate>1970-01-01</osgb:changeDate>
      <osgb:reasonForChange>New</osgb:reasonForChange>
      </osgb:changeHistory>
      <osgb:descriptiveGroup>Inland Water</osgb:descriptiveGroup>
      <osgb:descriptiveTerm>Direction Of Flow</osgb:descriptiveTerm>
      <osgb:orientation>2280</osgb:orientation>
      <osgb:physicalLevel>50</osgb:physicalLevel>
      <osgb:physicalPresence>Indicator</osgb:physicalPresence>
    - <osgb:point>
    - <gml:Point srsName="osgb:BNG">
      <gml:coordinates>318253.5,515169.5</gml:coordinates>
      </gml:Point>
      </osgb:point>
      </osgb:CartographicSymbol>
      </osgb:cartographicMember>
    - <osgb:cartographicMember>
    - <osgb:CartographicText fid="osgb1000001137059688">
      <osgb:featureCode>10090</osgb:featureCode>
      <osgb:version>4</osgb:version>
      <osgb:versionDate>2005-12-31</osgb:versionDate>
      <osgb:theme>Water</osgb:theme>
    - <osgb:anchorPoint>
    - <gml:Point srsName="osgb:BNG">
      <gml:coordinates>318295.5,515763.5</gml:coordinates>
      </gml:Point>
      </osgb:anchorPoint>
    - <osgb:changeHistory>
      <osgb:changeDate>1970-01-01</osgb:changeDate>
      <osgb:reasonForChange>New</osgb:reasonForChange>
      </osgb:changeHistory>
    - <osgb:changeHistory>
      <osgb:changeDate>2002-09-25</osgb:changeDate>
      <osgb:reasonForChange>Reclassified</osgb:reasonForChange>
      </osgb:changeHistory>
    - <osgb:changeHistory>
      <osgb:changeDate>2005-01-07</osgb:changeDate>
      <osgb:reasonForChange>TextChange</osgb:reasonForChange>
      </osgb:changeHistory>
    - <osgb:changeHistory>
      <osgb:changeDate>2005-11-09</osgb:changeDate>
      <osgb:reasonForChange>Attributes</osgb:reasonForChange>
      </osgb:changeHistory>
      <osgb:descriptiveGroup>Inland Water</osgb:descriptiveGroup>
      <osgb:make>Natural</osgb:make>
      <osgb:physicalLevel>50</osgb:physicalLevel>
    - <osgb:textRendering>
      <osgb:anchorPosition>2</osgb:anchorPosition>
      <osgb:font>1</osgb:font>
      <osgb:height>12</osgb:height>
      <osgb:orientation>3175</osgb:orientation>
      </osgb:textRendering>
      <osgb:textString>above Newlyn Datum 1972</osgb:textString>
      </osgb:CartographicText>
      </osgb:cartographicMember>

    The point is that in the following cartographic elements there are elements missing and thus i cannot keep the cartographic elements with values from elements into a e.g. class because not all of them are in there...

    could you give me a hint?

    thanks a lot!
    Monday, December 10, 2007 5:11 PM
  • What exactly is it that you want to achieve? Your first post talked about theme and descriptiveGroup elements and not all cartographicMember elements having those children but in the sample you posted, as far as I can see, all cartographicMember elements have those children. You can use code like this:

    Code Block

                XmlDocument xDoc = new XmlDocument();

                xDoc.Load(@"..\..\XMLFile1.xml");

                XmlNamespaceManager nsmgr = new XmlNamespaceManager(xDoc.NameTable);

                nsmgr.AddNamespace("osgb", "http://www.ordnancesurvey.co.uk/xml/namespaces/osgb");

                foreach (XmlElement member in xDoc.SelectNodes("//osgb:cartographicMember", nsmgr))
                {

                    XmlElement theme = member.SelectSingleNode(".//osgb:theme", nsmgr) as XmlElement;
                    if (theme != null)
                    {
                        Console.WriteLine("theme is {0}.", theme.InnerText);
                    }

                    XmlElement group = member.SelectSingleNode(".//osgb:descriptiveGroup", nsmgr) as XmlElement;

                    if (group != null)
                    {
                        Console.WriteLine("group is {0}.", group.InnerText);
                    }

                }

     

     

    That prints out the theme and group InnerText for those cartographicMember elements having such descendants.
    Monday, December 10, 2007 5:30 PM
  • hmm,

     

    many thanks for your reply! I wanted to do what i initially said but i didn't want to post a large xml file here.. unfortunately as you pointed out, indeed the part that i posted had cartographic members with all the elements and was not representative...

     

    however, i figured it out from your code! thx again!

     

    cheersSmile

    Friday, December 14, 2007 10:17 AM