Boyan's Blog

Snippets of code and fun.

  • Boyan's blog

    Mo update from Freddie Mercury

    • 1 Comments

    Seeing how Steve is doing a good job of advertising his mo, I thought I would do the same... to keep the competition alive!

    Here is how my mo is measuring up:

    Boyan

     

    Does it look vaguely familiar?

    Freddie

  • Boyan's blog

    Solving InfoPath "schema validation found non-data type" errors for xsi:nil fields

    • 1 Comments

    If you try to programaticaly set/remove values of fields in InfoPath, you might have come across the following error message:
    "Schema validation found non-data type errors"

    A number of blogs and MSDN articles describe what to do in this case. They work for setting values, however I could not find how to clear values.

    The problem

    Values that are non-string (DateTime, Time, Date, Boolean, Whole Number, Decimal) cannot be blank (Empty String). If a value is set to the emptry string you will get the error above, because the empty string is considered a string and you are trying to set it to a field that is non-string. When one of these non-string fields is blank, it has an attribute "xsi:nil" that is set to "true". As soon as you type a value in this field in InfoPath the attribute is cleared.

    The solution

    Therefore, if you are trying to set values programatically you need to clear the "xsi:nil" attribute, or set it to "false". And if you are clearing the value of such a field, then you need to place the "xsi:nil" attribute back in, or set it to "true".

    Other blogs on the internet say that clearing the value and setting the xsi:nil attribute to true is very simple, however the snippets of code they offer do not work.

    • This is because a nil field looks like so: <my:value />
    • After you type something, it looks like so: <my:value>123</my:value>
    • If you try and add the nil attribute in <my:value></my:value> you will get the "Schema validation found non-data type errors" error when you load the form.

    The solution is to follow the steps below, depending on what you need to do with your field.

    Editing a non-string field:

    • If you are going to try and programatically edit a field that is non-string, then you have to remove its "nil" attribute
    • Now you can change its value

    Code (as on all other blogs and articles, this piece was taken from http://blogs.msdn.com/infopath/archive/2006/11/28/the-xsi-nil-attribute.aspx):

    //Create a Navigator object for the main data source

    XPathNavigator xn = this.MainDataSource.CreateNavigator();

     

    //Create a navigator object for the field (node)

    //where we want to set the current date value

    XPathNavigator xnfield1 = xn.SelectSingleNode("/my:myFields/my:field1", this.NamespaceManager);

     

    //Check if the "nil" attribute exists on this node

    DeleteNil(xnfield1);

     

    //Create a new dateTime object for the current date

    DateTime curDate = new DateTime(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day);

     

    //Set the value of field1 to the current date in the

    //correct format: yyyy-mm-dd

    xnfield1.SetValue(curDate.GetDateTimeFormats().GetValue(5).ToString());

    public void DeleteNil(XPathNavigator node)
    {

    if (node.MoveToAttribute("nil", http://www.w3.org/2001/XMLSchema-instance))
          node.DeleteSelf();

    }

    Clearing a non-string field:

    • If you are going to programatically erase the value of a non-string field, then you have to re-construct the XML node to what InfoPath expects and add the "nil" attribute. This code is slightly different from dooke's Sharepoint place blog.

    Code (slight change from dooke's code):

    public static void InsertNil(XPathNavigator node)

    {

    if (!node.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance"))

          {

                string result = string.Empty;

                int endIndex = node.OuterXml.IndexOf(">");

                result = node.OuterXml.Substring(0, endIndex) + " xsi:nil=\"true\" />";

     

                node.OuterXml = result;

    }

    }

    This code will reconstruct the <my:value>123</my:value> to <my:value xsi:nil="true" /> which will clear the field.

    In my particular case, I wanted to clear the field, no matter what it was (string or non-string):

    private void ClearAllFields()

    {

     

    XPathNavigator node = xNav.SelectSingleNode(xPath, xNameSpace);

     

          if (node == null)

                return;

     

          try

          {

                // try this as a Date, Integer, Boolean node, set the nil value

                InsertNil(node);

          }

          catch

    {

                // if it is a string, the nil value won't work, so just set it to empty

                node.SetValue(string.Empty);

          }

    }

     

    public static void InsertNil(XPathNavigator node)

    {

    if (!node.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance"))

          {

                string result = string.Empty;

                int endIndex = node.OuterXml.IndexOf(">");

                result = node.OuterXml.Substring(0, endIndex) + " xsi:nil=\"true\" />";

     

                node.OuterXml = result;

    }

    }

Page 1 of 1 (2 items)