Reynan
Reynan

Reputation: 163

I Encounter error when SelectingSingleNode

EDIT: I think the reason is because of "UniversalShipment" xmlns. There is a link but i remove it for confidentiality. I can't pass through that node. help

This is my XML.

<UniversalInterchange xmlns="" version="1.0">
      <Header>
        <SenderID>1</SenderID>
        <RecipientID>2</RecipientID>
      </Header>
      <Body>
        <UniversalShipment xmlns="" version="1.1">
          <Shipment>   
            <CustomizedFieldCollection>
                <CustomizedField>
                  <Key>Documents Checked</Key>
                  <DataType>Boolean</DataType>
                  <Value>false</Value>
                </CustomizedField>
                <CustomizedField>
                  <Key>Date Completed</Key>
                  <DataType>DateTime</DataType>
                  <Value></Value>
                </CustomizedField>
            </CustomizedFieldCollection>
          </Shipment>
        </UniversalShipment>
      </Body>
    </UniversalInterchange>

I received null when getting singlenode. But when i try "Body" only in single node it add to bottom. if i tried to add it to UniversalShipment "Body/UniversalShipment" it encounters and error.

   XmlDocument doc=new XmlDocument();
    doc.Load("sample.xml");
    XmlNode customizedNode = doc.CreateElement("CustomizedField");
                XmlNode keyNode = doc.CreateElement("Key");
                XmlNode dataNode = doc.CreateElement("DataType");
                XmlNode valueNode = doc.CreateElement("Value");
                keyNode.InnerText = "hi";
                dataNode.InnerText = "hello";
                valueNode.InnerText = "bye";
                customizedNode.AppendChild(keyNode);
                customizedNode.AppendChild(dataNode);
                customizedNode.AppendChild(valueNode);
                doc.DocumentElement.SelectSingleNode("Body/UniversalShipment/Shipment/CustomizedFieldCollection").AppendChild(customizedNode);
    doc.Save("sample.xml");

Upvotes: 1

Views: 91

Answers (2)

Matt Hogan-Jones
Matt Hogan-Jones

Reputation: 3103

If you have default namespaces you will need to use an XmlNamespaceManager - however, you have two default namespaces so it's a little more complicated.

As you have completely removed the namespace URIs from your question I've invented my own:

<UniversalInterchange xmlns="firstdefaultnamespace" version="1.0">
  <Header>
    <SenderID>1</SenderID>
    <RecipientID>2</RecipientID>
  </Header>
  <Body>
    <UniversalShipment xmlns="seconddefaultnamespace" version="1.1">
      <Shipment>   
        <CustomizedFieldCollection>
            <CustomizedField>
              <Key>Documents Checked</Key>
              <DataType>Boolean</DataType>
              <Value>false</Value>
            </CustomizedField>
            <CustomizedField>
              <Key>Date Completed</Key>
              <DataType>DateTime</DataType>
              <Value></Value>
            </CustomizedField>
        </CustomizedFieldCollection>
      </Shipment>
    </UniversalShipment>
  </Body>
</UniversalInterchange>

If your first default namespace has a URI of firstdefaultnamespace and your second default namespace has a URI of seconddefaultnamespace you can do this:

    XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
    ns.AddNamespace("ns1", "firstdefaultnamespace");
    ns.AddNamespace("ns2", "seconddefaultnamespace");

    doc.DocumentElement.SelectSingleNode("ns1:Body/ns2:UniversalShipment/ns2:Shipment/ns2:CustomizedFieldCollection", ns).AppendChild(customizedNode);

However, you will have problems when you save your XML with the new XmlNodes - you are not creating it with any namespace so it will be saved with a new default namespace, which will override the default namespace on the UniversalShipment element.

I would strongly suggest you read more about XML namespacing.

If you want to create your elements and keep them within the inner default namespace, you'll need to do something like this:

    const string FirstNamespaceUri = "firstdefaultnamespace";
    const string SecondNamespaceUri = "seconddefaultnamespace";
    XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
    ns.AddNamespace("ns1", FirstNamespaceUri);
    ns.AddNamespace("ns2", SecondNamespaceUri);

    XmlNode customizedNode = doc.CreateElement("CustomizedField", SecondNamespaceUri);
    XmlNode keyNode = doc.CreateElement("Key", SecondNamespaceUri);
    XmlNode dataNode = doc.CreateElement("DataType", SecondNamespaceUri);
    XmlNode valueNode = doc.CreateElement("Value", SecondNamespaceUri);
    keyNode.InnerText = "hi";
    dataNode.InnerText = "hello";
    valueNode.InnerText = "bye";
    customizedNode.AppendChild(keyNode);
    customizedNode.AppendChild(dataNode);
    customizedNode.AppendChild(valueNode);

    doc.DocumentElement.SelectSingleNode("ns1:Body/ns2:UniversalShipment/ns2:Shipment/ns2:CustomizedFieldCollection", ns).AppendChild(customizedNode);

Upvotes: 1

seesharpconcepts
seesharpconcepts

Reputation: 190

XPath expression is not formed correctly in you case. Check this link for XPath guide: http://www.w3schools.com/xsl/xpath_syntax.asp

Working Xpath: doc.DocumentElement.SelectSingleNode("Body/UniversalShipment/Shipment/CustomizedFieldCollection").AppendChild(customizedNode);

If namespaces are specified in the XML, XmlNamespaceManager can be passed to XmlNode.SelectSingleNode as explained here!

Upvotes: 0

Related Questions