Пример #1
0
 /// <summary>
 /// Performs a custom equals test against two configured name objects using value semantics over the local name and namespace URI.
 /// </summary>
 /// <param name="a"> The first configured name to test. </param>
 /// <param name="b"> The second configured name object to test. </param>
 /// <returns> A value indicating whether the two configured name objects are equal using value semantics. </returns>
 private static bool TestEquals(XyzlName a, XyzlName b)
 {
     return((a.LocalName == b.LocalName) &&
            (a.NamespaceUri == b.NamespaceUri));
 }
Пример #2
0
        public async ValueTask <ISolderConfiguration> DeserializeAsync(XmlReader xmlReader, CancellationToken cancellationToken = default)
        {
            IXyzlName elementXyzlName = null, attributeXyzlName, previousElementXyzlName;

            ISolderConfiguration documentSolderConfiguration = null;
            ISolderConfiguration currentSolderConfiguration;

            Stack <ISolderConfiguration> contextStack;
            bool isEmptyElement, isTextElement;
            Dictionary <IXyzlName, string> attributes;

            IXmlLineInfo xmlLineInfo;

            if ((object)xmlReader == null)
            {
                throw new ArgumentNullException(nameof(xmlReader));
            }

            // setup contextual data
            attributes   = new Dictionary <IXyzlName, string>();
            contextStack = new Stack <ISolderConfiguration>();
            xmlLineInfo  = xmlReader as IXmlLineInfo;

            // walk the XML document
            while (await xmlReader.ReadAsync())
            {
                // determine node type
                if (xmlReader.NodeType == XmlNodeType.CDATA ||
                    xmlReader.NodeType == XmlNodeType.Text)                     // textual node
                {
                    // clear previous attributes
                    attributes.Clear();

                    // is this a text element?
                    isTextElement = this.IsTextElement(contextStack, elementXyzlName ?? new XyzlName());

                    // get the current XML configuration object as XML text object
                    currentSolderConfiguration = this.DeserializeFromXmlText(xmlLineInfo, contextStack, xmlReader.Value, isTextElement ? elementXyzlName : null);

                    // is this a text element? if so, deserialize into it in a special maner
                    if (isTextElement)
                    {
                        this.DeserializeFromXml(xmlLineInfo, contextStack, null, elementXyzlName, attributes, (IXyzlValue <string>)currentSolderConfiguration);
                    }
                }
                else if (xmlReader.NodeType == XmlNodeType.Element)                 // actual elements
                {
                    // DebugWrite(string.Format("{2} <{0}{1}>", xmlReader.LocalName, xmlReader.IsEmptyElement ? " /" : string.Empty, xmlReader.IsEmptyElement ? "empty" : "begin"));

                    // stash away previous element
                    //previousElementXyzlName = elementXyzlName;
                    // fixes a bug here
                    if (contextStack.Count > 0)
                    {
                        previousElementXyzlName = this.GetConfiguredName(contextStack.Peek());
                    }
                    else
                    {
                        previousElementXyzlName = null;
                    }

                    // create the element XML name
                    elementXyzlName = new XyzlName()
                    {
                        LocalName    = xmlReader.LocalName,
                        NamespaceUri = xmlReader.NamespaceURI
                    };

                    // is this an empty element?
                    isEmptyElement = xmlReader.IsEmptyElement;

                    // is this a text element?
                    isTextElement = this.IsTextElement(contextStack, elementXyzlName);

                    // clear previous attributes
                    attributes.Clear();

                    // iterate over attributes of current element
                    for (int ai = 0; ai < xmlReader.AttributeCount; ai++)
                    {
                        // traverse to next attribute
                        xmlReader.MoveToAttribute(ai);

                        // create the attribute XML name
                        attributeXyzlName = new XyzlName()
                        {
                            LocalName    = xmlReader.LocalName,
                            NamespaceUri = xmlReader.NamespaceURI
                        };

                        // append to attribute collection
                        attributes.Add(attributeXyzlName, xmlReader.Value);
                    }

                    // clear attribute name
                    attributeXyzlName = null;

                    // is this not a text element?
                    if (!isTextElement)
                    {
                        // deserialize current XML configuration object
                        currentSolderConfiguration = this.DeserializeFromXml(xmlLineInfo, contextStack, previousElementXyzlName, elementXyzlName, attributes, null);
                    }
                    else
                    {
                        // use 'dummy' current XML configuration object (the parent so depth counts are correct and IsTextElement() works)
                        currentSolderConfiguration = contextStack.Peek();
                    }

                    // check context stack depth for emptiness
                    if (contextStack.Count <= 0)
                    {
                        // document element is current element when no context present
                        documentSolderConfiguration = currentSolderConfiguration;
                    }

                    // push current XML configuration object as parent XML configuration object if there are children possible (no empty element)
                    if (!isEmptyElement)
                    {
                        contextStack.Push(currentSolderConfiguration);
                    }
                }
                else if (xmlReader.NodeType == XmlNodeType.EndElement)                 // closing element
                {
                    // DebugWrite(string.Format("end <{0}>", xmlReader.LocalName));

                    // create the element XML name
                    elementXyzlName = new XyzlName()
                    {
                        LocalName    = xmlReader.LocalName,
                        NamespaceUri = xmlReader.NamespaceURI
                    };

                    // is this a text element?
                    isTextElement = this.IsTextElement(contextStack, elementXyzlName);

                    // sanity check
                    if (contextStack.Count < 1)
                    {
                        throw new XyzlException(string.Format("TODO: error message"));
                    }

                    // pop element off stack (unwind)
                    contextStack.Pop();

                    // clear attribute name
                    elementXyzlName = null;
                }
            }

            // sanity check
            if (contextStack.Count != 0)
            {
                throw new XyzlException(string.Format("TODO: error message"));
            }

            // ...and I'm spent!
            return(documentSolderConfiguration);
        }