0

I am trying to create a list where each item in the list contains the name of the package and the location where is it saved. I created a constructor with two variables name and location. Then I created a list consisting of that constructor. I am able to grab the name but the location is giving me some trouble. Also if the node does not have a location then I want an empty string for that item in the list. [see Result list I want for clarification].

My XML:

<project containsDynamicContent="true" xmlns="http://www.developer.cognos.com/schemas/bmt/60/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.developer.cognos.com/schemas/bmt/60/1 BMTModelSpecification.xsd">
    <packages>
        <package>
            <name>name1</name>
            <lastPublishedCMPath>Location_name1</lastPublishedCMPath>
        </package>
    </packages>
    <packages>
        <package>
            <name>name2</name>
        </package>
    </packages>
    <packages>
        <package>
            <name>name3<name>
            <lastPublishedCMPath>Location_name3</lastPublishedCMPath>
        </package>
    </packages>
</project>

My C# Code: constructor:

public class PackageNameAndLocation
    {
        public string PackageName { get; set; }
        public string LastLocation { get; set; }
    }

The rest of the code:

    private List<string> m_publishedCMPathList = new List<string>();
    private List<PackageNameAndLocation> m_pnalList = new List<PackageNameAndLocation>();

    Configuration.Instance.NSManager = new XmlNamespaceManager(xmlDoc.NameTable);
    Configuration.Instance.NSManager.AddNamespace("cg", mlDoc.DocumentElement.NamespaceURI);

    XmlNodeList m_packageName = xmlDoc.DocumentElement.SelectNodes("//cg:project/cg:packages/cg:package/cg:name", Configuration.Instance.NSManager);
    string m_lastLocation = string.Empty;

foreach (XmlNode name in m_packageName)
            {
                PackageNameAndLocation m_pnalClass = new PackageNameAndLocation();
                m_pnalClass.PackageName  = name.InnerText;
                XmlNode m_lastPublishedCMPath = name.SelectSingleNode("//cg:lastPublishedCMPath", Configuration.Instance.NSManager);
                if(m_lastPublishedCMPath != null)
                {
                    m_lastLocation = m_lastPublishedCMPath.InnerText;
                }
                else
                {
                    m_lastLocation = "";

                }
                m_pnalClass.LastLocation = m_lastLocation;
                m_pnalList.Add(m_pnalClass);
            }

My Result List:
[0] name1
    location_name1
[1] name2
    location_name1
[2] name3
    location_name1

Result List I want:
[0] name1
    location_name1
[1] name2
    "" [Empty String]
[2] name3
    location_name3

Can someone help me out please?? Is is something with the xpath or the code itself? Thank you very much!

Sahil Gupta
  • 285
  • 2
  • 5
  • 16
  • in your code you are using namespace but your xml doesnt contain any namespace..kindly show your complete xml with all namespaces – Anirudha Jul 16 '13 at 17:41
  • Hopefully that helps! sorry the original xml is too big to put on here so I created this one myself. – Sahil Gupta Jul 16 '13 at 17:47

1 Answers1

1

Use linq2xml..Its simple to use..

XElement doc=XElement.Load("yourXml.xml");
XNamespace ns="http://www.developer.cognos.com/schemas/bmt/60/1";

m_pnalList=doc.Descendants(ns+"package")
              .Select(d=>
                  new PackageNameAndLocation
                  {
                       PackageName=(string)d.Element(ns+"name"),
                       LastLocation=(string)d.Element(ns+"lastPublishedCMPath")
                  }
                  )
               .ToList<PackageNameAndLocation>();

If you want to stick with xmldocument!

1>You don't need the methods in PackageNameAndLocation..Just keep the properties

2>this should do

XmlNodeList m_package = xmlDoc.DocumentElement.SelectNodes("//cg:package", Configuration.Instance.NSManager);
string m_lastLocation = string.Empty;

foreach (XmlNode package in m_package)
            {
                PackageNameAndLocation m_pnalClass = new PackageNameAndLocation();
                m_pnalClass.PackageName  = package.SelectSingleNode("//cg:name").InnerText;
                XmlNode m_lastPublishedCMPath =  name.SelectSingleNode("//cg:lastPublishedCMPath", Configuration.Instance.NSManager);
.....
Anirudha
  • 32,393
  • 7
  • 68
  • 89
  • is there anyway for me to use xmldocument? This code was originally written by my superior and I cannot change how the xml is being grabbed. Sorry if I sound ambiguous I am kind of new to c# and xpath. – Sahil Gupta Jul 16 '13 at 17:59
  • haha hey I don't make the rules. However, I thought for sure that would've worked but it is still showing me the result the I posted in my question. Not the result I want. – Sahil Gupta Jul 16 '13 at 18:17
  • @SahilGupta are you sure you used `name.SelectSingleNode`!that should have worked – Anirudha Jul 16 '13 at 18:21
  • I have edited the code to reflect what I have now. As you can see I took your advice and used name.SelectSingleNode – Sahil Gupta Jul 16 '13 at 18:28