/// <summary>
        /// Outputs a set of fields to XML using the field format specified in the IEEE XMPP IoT extensions.
        /// </summary>
        /// <param name="Xml">XML output.</param>
        /// <param name="Fields">Fields to output.</param>
        /// <param name="Errors">Errors to report.</param>
        /// <param name="Id">Request identity.</param>
        /// <param name="Done">If the readout is done.</param>
        /// <param name="IsIncluded">Optional callback method that can be used to filter output. If null, all fields are output.</param>
        /// <returns>If the response is non-empty, i.e. needs to be sent.</returns>
        public static bool OutputFields(XmlWriter Xml, IEnumerable <Field> Fields, IEnumerable <ThingError> Errors, string Id, bool Done, IsIncludedDelegate IsIncluded)
        {
            Xml.WriteStartElement("resp", SensorClient.NamespaceSensorData);
            Xml.WriteAttributeString("id", Id);

            if (!Done)
            {
                Xml.WriteAttributeString("more", "true");
            }

            bool Result = OutputFields(Xml, Fields, Errors, IsIncluded);

            Xml.WriteEndElement();

            if (Done)
            {
                return(true);
            }
            else
            {
                return(Result);
            }
        }
        /// <summary>
        /// Outputs a set of fields to XML using the field format specified in the IEEE XMPP IoT extensions.
        /// </summary>
        /// <param name="Xml">XML output.</param>
        /// <param name="Fields">Fields to output. Can be null.</param>
        /// <param name="Errors">Any errors to output. Can be null.</param>
        /// <param name="IsIncluded">Optional callback method that can be used to filter output. If null, all fields are output.</param>
        /// <returns>If the response is non-empty, i.e. needs to be sent.</returns>
        public static bool OutputFields(XmlWriter Xml, IEnumerable <Field> Fields, IEnumerable <ThingError> Errors, IsIncludedDelegate IsIncluded)
        {
            ThingReference LastThing     = null;
            DateTime       LastTimestamp = DateTime.MinValue;
            bool           TimestampOpen = false;
            bool           NodeOpen      = false;
            bool           Checked;
            bool           Empty = true;

            if (Fields != null)
            {
                foreach (Field Field in Fields)
                {
                    Checked = false;

                    if (LastThing is null || !LastThing.SameThing(Field.Thing))
                    {
                        if (IsIncluded != null && !IsIncluded(Field.Name, Field.Timestamp, Field.Type))
                        {
                            continue;
                        }

                        Checked = true;

                        if (TimestampOpen)
                        {
                            Xml.WriteEndElement();
                            TimestampOpen = false;
                        }

                        if (NodeOpen)
                        {
                            Xml.WriteEndElement();
                            NodeOpen = false;
                        }

                        LastThing     = Field.Thing;
                        LastTimestamp = DateTime.MinValue;

                        if (!string.IsNullOrEmpty(LastThing.NodeId))
                        {
                            Xml.WriteStartElement("nd");
                            Xml.WriteAttributeString("id", LastThing.NodeId);

                            if (!string.IsNullOrEmpty(LastThing.SourceId))
                            {
                                Xml.WriteAttributeString("src", LastThing.SourceId);
                            }

                            if (!string.IsNullOrEmpty(LastThing.Partition))
                            {
                                Xml.WriteAttributeString("pt", LastThing.Partition);
                            }

                            NodeOpen = true;
                        }
                    }

                    if (LastTimestamp != Field.Timestamp)
                    {
                        if (IsIncluded != null && !IsIncluded(Field.Name, Field.Timestamp, Field.Type))
                        {
                            continue;
                        }

                        Checked = true;

                        if (TimestampOpen)
                        {
                            Xml.WriteEndElement();
                            TimestampOpen = false;
                        }

                        LastTimestamp = Field.Timestamp;

                        Xml.WriteStartElement("ts");
                        Xml.WriteAttributeString("v", XML.Encode(LastTimestamp));

                        TimestampOpen = true;
                    }

                    if (!Checked && IsIncluded != null && !IsIncluded(Field.Name, Field.Timestamp, Field.Type))
                    {
                        continue;
                    }

                    OutputField(Xml, Field);
                    Empty = false;
                }
            }

            if (Errors != null)
            {
                foreach (ThingError Error in Errors)
                {
                    if (LastThing is null || !LastThing.SameThing(Error))
                    {
                        if (TimestampOpen)
                        {
                            Xml.WriteEndElement();
                            TimestampOpen = false;
                        }

                        if (NodeOpen)
                        {
                            Xml.WriteEndElement();
                            NodeOpen = false;
                        }

                        LastThing     = Error;
                        LastTimestamp = DateTime.MinValue;

                        if (!string.IsNullOrEmpty(LastThing.NodeId))
                        {
                            Xml.WriteStartElement("nd");
                            Xml.WriteAttributeString("id", LastThing.NodeId);

                            if (!string.IsNullOrEmpty(LastThing.SourceId))
                            {
                                Xml.WriteAttributeString("src", LastThing.SourceId);
                            }

                            if (!string.IsNullOrEmpty(LastThing.Partition))
                            {
                                Xml.WriteAttributeString("pt", LastThing.Partition);
                            }

                            NodeOpen = true;
                        }
                    }

                    if (LastTimestamp != Error.Timestamp)
                    {
                        if (TimestampOpen)
                        {
                            Xml.WriteEndElement();
                            TimestampOpen = false;
                        }

                        LastTimestamp = Error.Timestamp;

                        Xml.WriteStartElement("ts");
                        Xml.WriteAttributeString("v", XML.Encode(LastTimestamp));

                        TimestampOpen = true;
                    }

                    OutputError(Xml, Error);
                    Empty = false;
                }
            }

            if (TimestampOpen)
            {
                Xml.WriteEndElement();
            }

            if (NodeOpen)
            {
                Xml.WriteEndElement();
            }

            return(!Empty);
        }
 /// <summary>
 /// Outputs a set of fields to XML using the field format specified in the IEEE XMPP IoT extensions.
 /// </summary>
 /// <param name="Xml">XML output.</param>
 /// <param name="Fields">Fields to output.</param>
 /// <param name="Id">Request identity.</param>
 /// <param name="Done">If the readout is done.</param>
 /// <param name="IsIncluded">Optional callback method that can be used to filter output. If null, all fields are output.</param>
 /// <returns>If the response is non-empty, i.e. needs to be sent.</returns>
 public static bool OutputFields(XmlWriter Xml, IEnumerable <Field> Fields, string Id, bool Done, IsIncludedDelegate IsIncluded)
 {
     return(OutputFields(Xml, Fields, null, Id, Done, IsIncluded));
 }