Alen Kopic
Alen Kopic

Reputation: 121

parsing xsd complexType recursively

private ElementDefinition ParseComplexType(XElement complexType, string nameValue = "")
        {
            var name = complexType.Attribute("name");

            ElementDefinition element = new ElementDefinition()
            {
                Elements = new List<ElementDefinition>(),
                ElementName = name != null ? name.Value : string.Empty
            };

            foreach (var el in complexType.Descendants().Where(k => k.Parent.Parent == complexType && k.Name.LocalName == "element"))
            {
                ElementDefinition tempElement = new ElementDefinition();
                var tempName = el.Attribute("name");
                var tempType = el.Attribute("type");

                if (tempName != null)
                {
                    tempElement.ElementName = tempName.Value;
                }
                if (tempType != null)
                {
                    var tempTypeValue = tempType.Value.Substring(tempType.Value.IndexOf(":") + 1, tempType.Value.Length - tempType.Value.IndexOf(":") - 1);
                    if (tipovi.Contains(tempTypeValue))
                    {
                        tempElement.ElementType = tempTypeValue;
                        element.Elements.Add(tempElement);
                    }
                    else
                    {
                        complexType = GetComplexType(tempTypeValue);
                        element.Elements.Add(ParseComplexType(complexType, tempName.Value));

                    }
                }

            }
            if (nameValue != "") element.ElementName = nameValue;

            return element;
        }

Hi so this is a function i use for parsing XSD complexTypes.

This is a xsd schema i use xsd Schema. I have problem parsing complexType element at line 14.

It only parses shipTo element, skipping billTo and parsing badly items.

The result is http://pokit.org/get/?b335243094f635f129a8bc74571c8bf2.jpg

Which fixes can i apply to this function in order to work properly?

PS. "tipovi" is list of xsd supported types, e.g. string, positiveInteger....

EDITED:

private XElement GetComplexType(string typeName)
        {
            XNamespace ns = "http://www.w3.org/2001/XMLSchema";
            string x = "";
            foreach (XElement ele in xsdSchema.Descendants())
            {

                if (ele.Name.LocalName == "complexType" && ele.Attribute("name") != null)
                {

                    x = ele.Attribute("name").Value;
                    if (x == typeName)
                    {
                        return ele;
                    }
                }
            }
            return null;
        } 

GetComplexType finds complexType definition of an element type. For example, for "PurchaseOrderType" (line 10) it returns element at line 14.

Upvotes: 0

Views: 740

Answers (1)

user2819245
user2819245

Reputation:

NOTE: This is only a partial answer as it only explains the issue regarding the skipped "billTo" element. The code as presented in the question has many more issues.


The problem regarding skipping of the billTo element

The complexType variable is used in the predicate for the Linq method Where in the foreach loop:

 complexType.Descendants().Where(k => k.Parent.Parent == complexType && k.Name.LocalName == "element"))

This lambda expression uses the variable complexType, not merely its value.

By assigning another value to complexType deep down inside your foreach loop

complexType = GetComplexType(tempTypeValue);

you also change the logic of which elements are filtered by the predicate of the Where method in the the foreach loop.


The Fix

The solution is rather simple: Do not change the complexType variable within the foreach loop. You could do the call of GetComplexType like this:

XElement complexTypeUsedByElement = GetComplexType(tempTypeValue);
element.Elements.Add(ParseComplexType(complexTypeUsedByElement, tempName.Value));

Upvotes: 1

Related Questions