Problems with xsi:nil - InfoPath Dev
in

InfoPath Dev

Problems with xsi:nil

Last post 03-12-2009 08:23 PM by Jimmy. 3 replies.
Page 1 of 1 (4 items)
Sort Posts: Previous Next
  • 02-26-2009 09:52 AM

    Problems with xsi:nil

    My schema contains some nillable fields (integer, datetime, and others mentioned in http://blogs.msdn.com/infopath/archive/2006/11/28/the-xsi-nil-attribute.aspx).

     In my template.xml, these fields contain the attribute xsi:nil="true", but the xsi:nil is not present in sampledata.xml.  This makes sense becase the arribute is not truly an attribute of my schema (I did not add it via code or in Design).

     However, after I submit a form, the xsi:nil="true" is present in the raw xml file that is saved.  Why is it here if it's not part of the true schema?

     I have custom code that I use to update a file to the new form template.  I use sampledata.xml as my template, so xsi:nil is not there.  Then, after I update the form, when I try to submit an error is thrown on the date or integer or whatever because a value is expected.  So, in my update code, I tried manually adding an xsi:nil attribute to the field, but then I get an error that nil is unexpected according to the schema.

    When I step through the old xml file when it is being uploaded, xsi:nil is treated as an attribute, and is contained in IXMLDOMNode.attributes, so why doesn't it throw an error under this circumstance?

     I guess I am just at a loss on how this "attribute" should be treated.  How can it be in the xml and treated exactly like attribute in one scenario but not another?

    Any clarification anyone can give is much appreciated.  Thanks!

    Filed under: ,
  • 02-26-2009 06:59 PM In reply to

    Typically in XML, it is illegal for a field designated as a numerical value in the schema to not have a value.  There is no such thing as a "blank" number.  InfoPath manages to work around this by using a little trick in the schema:

     <xsd:element name="field1" nillable="true" type="xsd:integer"/>

    This means that if the node is given the xsi:nil="true" attribute in the actual XML, it is allowed to be blank.

    That's a little background, now as for your actual issue.  It is in fact possible to manually add the xsi:nil attribute and have the form pass schema validation, but there are two things to make sure when you do this:

    • The field can't be set as "cannot be blank" in InfoPath.  That is, it should have nillable="true" in the schema as above.
    • The attribute must have the correct namespace.  It is not enough to just add nil="true" as an attribute or xsi:nil="true" without specifying the correct namespace.  The namespace URI should be http://www.w3.org/2001/XMLSchema-instance.

    Is there perhaps one of these items that is not being satisfied in your code?

    Jimmy Rishe / Software Developer / Microsoft MVP
    Qdabra Software
  • 03-12-2009 12:22 PM In reply to

    Hi Jimmy,

    Thanks for your response, and sorry for my delayed reply.  I'm sure you were eagerly watching and waiting.  :)

    The schema does contain nillable="true" for the elements in question, and all documents and schemas contain that namespace.  But your hint about the namespace did help me track down a solution!

    Our form update process obviously needs to be worked on, but currently it works like this:

    1. When a user opens an xml document, we check the XDocument.Solution.URI with the URI of the most recent form template.  If they do not match, we perform the custom upgrade in code.
    2. We then recursively walk through the new schema and the existing xml document node by node and compare, copying over any existing information.
    3. To know the structure of the new schema, we are loading sample.xml into an IXMLDOMDocument2
    4. In the scenarios when a BOOL, DATE, INT etc was in the schema with no value, the xsi:nil attribute would show up on the old node (from the xml document), but not the new node (from sample.xml).
    5. When I tried manually adding an attribute to the new node I would get validation errors, as stated above.

    What clued me in was that when I created the new attribute, the IXMLDOMNode.namespaceURI was null and not ...XMLSchema-instance as you pointed out.  Since this member is read only, I cloned the old attribute and then added it to the new node.

    if (OldNode.attributes.getNamedItem("xsi:nil") != null)
    {
        IXMLDOMNode xsinil = OldNode.attributes.getNamedItem("xsi:nil").cloneNode(true);
        NewNode.attributes.setNamedItem(xsinil);
    }

    This seemed to do the trick!  Thanks again for the help and getting me in the right direction.

  • 03-12-2009 08:23 PM In reply to

    Hello again,

     Glad you got it worked out.  Your solution seems like a pretty good one and I think cloning the attribute is probably as good as any other approach.

    Just so you know, you can manually create an xsi:nil attribute like this:

    IXMLDOMNode nilAttr = thisXDocument.DOM.createNode(DOMNodeType.NODE_ATTRIBUTE, "nil", "http://www.w3.org/2001/XMLSchema-instance");
    nilAttr.nodeValue =
    "true";

    Jimmy Rishe / Software Developer / Microsoft MVP
    Qdabra Software
Page 1 of 1 (4 items)
Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.