Link to home
Start Free TrialLog in
Avatar of xRalf
xRalf

asked on

No elements when reading XML

Hi,
I'm reading XML file of the following structure.

<?xml version="1.0" encoding="utf-8"?>
<PriceList version="1.0" application="some text" note="some text" xmlns="http://...xsdfile.xsd">
  <Products>
    <ProductItem>
    </ProductItem>
      <ProductItem>
    </ProductItem>
<ProductItem>
    </ProductItem>
</Products>
</Pricelist>

with this code snippet.

foreach (XmlNode pictureNode in doc.DocumentElement.SelectNodes("ProductItem"))
{
   // processing
}

The problem is that doc.DocumentElement.SelectNodes("ProductItem") selects no elements.


When I change the XML structure to

<?xml version="1.0" encoding="utf-8"?>
  <Products>
      <ProductItem>
    </ProductItem>
<ProductItem>
    </ProductItem>
<ProductItem>
    </ProductItem>
</Products>

everything is OK. Where is the mistake?

thanks
Avatar of TimCottee
TimCottee
Flag of United Kingdom of Great Britain and Northern Ireland image

Hello xRalf,

The problem is that you are not observing the hierarchy of your document structure. In the first situation the  is the documentElement but the first level below that is  not the  elements. So you need to use:

doc.DocumentElement.SelectNodes("Products/ProductItem")

To get all the  elements contained with the  element.

Regards,

TimCottee
try

foreach (XmlNode pictureNode in doc.DocumentElement.SelectNodes("Products"))
{
   pictureNode.innerXML...
}

do a foreach for the inner node to get the value...

I will change the loop like this

foreach (XmlNode pictureNode in doc.DocumentElement.SelectNodes("//Products/ProductItem"))
{
   // processing
}
You can also use "//Products".  The expression is saying in all nodes, return all nodes with tagname of 'products'.  If you leave out the '//', then you are saying, in the current node return all of the nodes with tagname of 'products'.

Avatar of xRalf
xRalf

ASKER

Thanks,

but none of the solutions works. There are approximately 10000 items of ProductItem but the for cycle executes 0 times. It works only when I delete PriceList tags from XML file.

The code

XmlNode node = doc.DocumentElement.SelectSingleNode("PriceList") doesn't work either.

node will be null after this statement.
Avatar of xRalf

ASKER

When I delete the attributes of XML as follows it didn't help either. What is bad with this XML?

<?xml version="1.0" encoding="utf-8"?>
<PriceList>
  <Products>
    <ProductItem>
    </ProductItem>
      <ProductItem>
    </ProductItem>
<ProductItem>
    </ProductItem>
</Products>
</Pricelist>
I found the problem.  The XML you are using has a default name space.  The xmlns="http://...xsdfile.xsd" sets the PriceList node and all of its children to that default namespace.  The XPath you are specifying does not contain the namespace reference so it is searching for nodes that are not members of the namespace.  

The following fixes your code by specifying through the NameSpaceManager what namespace to use
            string XmlStr = @"<?xml version='1.0' encoding='utf-8'?>
<PriceList version='1.0' application='some text' note='some text' xmlns='http://...xsdfile.xsd'>
  <Products>
    <ProductItem>One</ProductItem>
    <ProductItem>Two</ProductItem>
    <ProductItem>Three</ProductItem>
  </Products>
</PriceList>";
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(XmlStr);
            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
            nsmgr.AddNamespace("default", "http://...xsdfile.xsd");  //Create reference to the default namespace
 
            XmlNodeList nodeList = doc.SelectNodes("//default:ProductItem", nsmgr);  //Reference the ProductItem node in the default namespace
            if (nodeList.Count == 0)
                System.Console.WriteLine("No items found");
            foreach (XmlNode pictureNode in nodeList)
            {
                System.Console.WriteLine(pictureNode.InnerText);
            }

Open in new window

Avatar of xRalf

ASKER

Hi MogalManic,

but here is no namespace

<?xml version="1.0" encoding="utf-8"?>
<PriceList>
  <Products>
    <ProductItem>
    </ProductItem>
      <ProductItem>
    </ProductItem>
<ProductItem>
    </ProductItem>
</Products>
</Pricelist>
When there is no namespace, you do NOT specify the namespace in the xpath.  So the xpath is just "//ProductItem"  (the // is still important)
try this one - i think i missed the price list node in my reference to the productimte

XmlNodeList = doc.DocumentElement.SelectNodes("//PriceList/Products/ProductItem");

for (XmlNode node in XmlNodeList)
{
    // node is now the product item node here....
}

the above code should work
Avatar of xRalf

ASKER

Hi,

I tried the code from every comment but only code from MogalManic is working. I rewritten it as follows (in codesnippet).
nodeList contains the nodes I was looking for, but when I uncomment the inner foreach loop, it doesn't find nothing. Is there some mistake?

Other interesting thing is that when I delete from XML "version='1.0' application='some text' note='some text' xmlns='http://...xsdfile.xsd'" it doesn't find anything. How are namespaces working? I know nothing about them.

thanks
XmlDocument doc = new XmlDocument();
doc.Load(@"D:\pricelist.xml");
 
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("default", "http://www....xsd");  //Create reference to the default namespace
 
XmlNodeList nodeList = doc.SelectNodes("//default:ProductItem", nsmgr);  //Reference the ProductItem node in the default namespace
            
            foreach (XmlNode pictureNode in nodeList)
            {
                MessageBox.Show(pictureNode.InnerText);
 
                //foreach (XmlNode pctNode in pictureNode.SelectNodes("//default:ProductPictures/ProductPictureItem/ProductPictureDetail", nsmgr))
                //{
                //    MessageBox.Show(pctNode.InnerText);
                //}
            }

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of MogalManic
MogalManic
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial