/// <summary>
 /// Checks that the current content node is an element with the given <see cref="XmlReader.LocalName"/> and <see
 /// cref="XmlReader.NamespaceURI"/> and advances the reader to the next node.
 /// </summary>
 /// <param name="reader">
 /// An <see cref="XmlReader"/> object.
 /// </param>
 /// <param name="name">
 /// The local name of the element.
 /// </param>
 /// <param name="ns">
 /// The namespace URI of the element.
 /// </param>
 public static void ReadEndElement(this XmlReader reader, string name, string ns)
 {
     if (reader == null)
     {
         throw new ArgumentNullException(nameof(reader));
     }
     reader.AssertEndElement(name, ns);
     reader.ReadEndElement();
 }
        private void ReadXmlProperties(XmlReader reader)
        {
            var list = new List <PropertyExtractor>();

            reader.MoveToContent();
            reader.AssertStartElement("Properties", SchemaAnnotations.NAMESPACE);
            Precedence = reader.HasAttribute("precedence")
                                ? reader.GetAttribute("precedence").IfNotNull(v => v.Parse <ExtractorPrecedence>())
                                : default(ExtractorPrecedence);
            reader.ReadStartElement("Properties", SchemaAnnotations.NAMESPACE);
            while (reader.NodeType == XmlNodeType.Element)
            {
                var name = new XmlQualifiedName(reader.LocalName, reader.NamespaceURI);
                var mode = reader.HasAttribute("mode")
                                        ? reader.GetAttribute("mode").IfNotNull(v => v.Parse <ExtractionMode>())
                                        : reader.HasAttribute("promoted")
                                                ? Convert.ToBoolean(reader.GetAttribute("promoted"))
                                                        ? ExtractionMode.Promote
                                                        : default(ExtractionMode)
                                                : default(ExtractionMode);
                var qnameValueMode = reader.HasAttribute("qnameValue")
                                        ? reader.GetAttribute("qnameValue").IfNotNull(v => v.Parse <QNameValueExtractionMode>())
                                        : QNameValueExtractionMode.Default;
                if (reader.HasAttribute("xpath"))
                {
                    var xpathExpression = reader.GetAttribute("xpath");
                    var extractor       = qnameValueMode == QNameValueExtractionMode.Default
                                                ? new XPathExtractor(name, xpathExpression, mode)
                                                : new QNameValueExtractor(name, xpathExpression, mode, qnameValueMode);
                    list.Add(extractor);
                }
                else if (reader.HasAttribute("value"))
                {
                    var extractor = new ConstantExtractor(name, reader.GetAttribute("value"), mode);
                    list.Add(extractor);
                }
                else if (!reader.HasAttribute("mode"))
                {
                    throw new ConfigurationErrorsException("ExtractionMode is missing for PropertyExtractor without a Value or an XPath.");
                }
                else
                {
                    var extractor = new PropertyExtractor(name, mode);
                    list.Add(extractor);
                }
                reader.Read();
            }
            if (!reader.EOF)
            {
                reader.AssertEndElement("Properties", SchemaAnnotations.NAMESPACE);
                reader.ReadEndElement();
            }
            Extractors = list.ToArray();
        }
 /// <summary>
 /// Checks that the current content node is an element with the given <see cref="XmlReader.LocalName"/> and <see
 /// cref="XmlReader.NamespaceURI"/> and advances the reader to the next node.
 /// </summary>
 /// <param name="reader">
 /// An <see cref="XmlReader"/> object.
 /// </param>
 /// <param name="name">
 /// The local name of the element.
 /// </param>
 /// <param name="ns">
 /// The namespace URI of the element.
 /// </param>
 public static void ReadEndElement(this XmlReader reader, string name, string ns)
 {
     reader.AssertEndElement(name, ns);
     reader.ReadEndElement();
 }