Получить имя тега сложного объекта из XML-схемы в C # - PullRequest
0 голосов
/ 28 марта 2019

Я хотел бы спросить, есть ли способ получить имена тегов, связанные с данным «именем сложного типа» (из сложного объекта внутри XSD (определение схемы XML)) в C # (.NET Framework 4.5).

Результат, который я хотел бы получить: если я ищу WhateverTypeName1, должно быть возвращено значение "childoftypeone".

Допустим, у нас есть следующий фрагмент XSD:

<xs:complexType name="ParentType">
    <xs:choice>
        <xs:element name="childoftypeone" type="WhateverTypeName1"/>
        <xs:element name="childoftypetwo" type="OtherTypeName"/>
    </xs:choice>
</xs:complexType>

<!-- after some declarations -->

<xs:complexType name="WhateverTypeName1">
    <xs:sequence>
        <!-- other elements from sequence -->
    </xs:sequence>
</xs:complexType>

Из типа XmlSchema я могу получить XmlSchemaComplexObject, выполнив поиск WhateverTypeName1 следующим образом:

var schema = new XmlSchema(); // load the XSD here.

var arr = new string[] { "WhateverTypeName1" };

var type = schema.Items
    .OfType<XmlSchemaObject>()

    // we can search matching the type here, put this way just to be concise
    .Where(w => w.GetType().Name.ToLower().Contains("complex"))
    .Select(s => (XmlSchemaComplexType)s)
    .FirstOrDefault(w => arr.Contains(w.Name));

Дело в том, что из этого XmlSchemaComplexType объекта мне не удалось сопоставить его с объявлением тега "childoftypeone" в ParentType (<xs:element name="childoftypeone" type="WhateverTypeName1"/>).

Мне удалось получить это сопряжение, только если я ищу его родительский объект (ParentType) и просматриваю его свойство Particle. Тем не менее, я думаю, что невозможно определить, где этот тип используется (например, ParentType) из его собственного XmlSchemaComplexType

Как я мог это сделать?

1 Ответ

0 голосов
/ 28 марта 2019

В конце концов, я разработал своего рода метод рекурсивного поиска, чтобы получить то, что мне было нужно, поскольку мне не удалось найти внутри пространства имен System.Xml ничего, что могло бы дать мне что-то близкое к тому, чего я достиг.

Это довольно простой / неоптимизированный код, и я не тестировал его подробно, но он работает.Он возвращает Dictionary<string, HashSet<string>>, где ключи - это имена типов внутри файла XSD (которые также являются именами классов из файла .cs, сгенерированного XSD.exe) и теги, в которых используются эти типы.

Здесь следует:

public Dictionary<string, HashSet<string>> GetTagsByType(
    ICollection<XmlSchemaObject> schemaObjects)
{
    var result = new Dictionary<string, HashSet<string>>();

    var xmlElements = schemaObjects
        .Where(w => w.GetType() == typeof(XmlSchemaElement))
        .ToArray();

    var types = schemaObjects
        .Where(w => w.GetType() == typeof(XmlSchemaComplexType))
        .ToArray();

    foreach (var item in xmlElements)
    {
        var el = (XmlSchemaElement)item;

        if (string.IsNullOrEmpty(el.Name) ||
            el.SchemaTypeName == null ||
            string.IsNullOrEmpty(el.SchemaTypeName.Name))
        {
            continue;
        }

        if (!result.ContainsKey(el.SchemaTypeName.Name))
        {
            result.Add(el.SchemaTypeName.Name, new HashSet<string> { el.Name });
        }
        else
        {
            result[el.SchemaTypeName.Name].Add(el.Name);
        }
    }

    foreach (var type in types)
    {
        var t = (XmlSchemaComplexType)type;

        if (t.Particle == null)
        {
            continue;
        }

        var isSubClassOfGroupBase = t.Particle.GetType()
            .IsSubclassOf(typeof(XmlSchemaGroupBase));

        if (!isSubClassOfGroupBase)
        {
            continue;
        }

        var items = ((XmlSchemaGroupBase)t.Particle)
            .Items
            .OfType<XmlSchemaObject>()
            .ToArray();

        var res = GetTagsByType(items);

        foreach (var item in res.Keys)
        {
            if (result.ContainsKey(item))
            {
                foreach (var r in res[item])
                {
                    result[item].Add(r);
                }
            }
            else
            {
                result.Add(item, res[item]);
            }
        }
    }

    return result;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...