从 XML 文件推断的 XmlSchema - 如何遍历 XSD 中的所有元素?

时间:2023-03-30
本文介绍了从 XML 文件推断的 XmlSchema - 如何遍历 XSD 中的所有元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我有一个 XML 文件,我正在使用 XmlSchemaInference 类在运行时推断其 XSD 架构.

I have an XML file and I'm inferring its XSD schema in run-time, using the XmlSchemaInference class.

示例文件:

<products>
    <product id="1" name="t-shirt">
        <size name="medium"/>
        <size name="large"/>
        <price>
            <net>10</net>
            <gross>25</gross>
        </price>
    </product>
    <product id="2" name="computer mouse">  
        <price>
            <net>50</net>       
        </price>
    </product>
</products>

它确实有效 - 它很好地推断了架构:

It does work - it infers the schema nicely:

<?xml version="1.0"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="products">
    <xs:complexType>
      <xs:sequence>
        <xs:element maxOccurs="unbounded" name="product">
          <xs:complexType>
            <xs:sequence>
              <xs:element minOccurs="0" maxOccurs="unbounded" name="size">
                <xs:complexType>
                  <xs:attribute name="name" type="xs:string" use="required" />
                </xs:complexType>
              </xs:element>
              <xs:element name="price">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="net" type="xs:unsignedByte" />
                    <xs:element minOccurs="0" name="gross" type="xs:unsignedByte" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
            <xs:attribute name="id" type="xs:unsignedByte" use="required" />
            <xs:attribute name="name" type="xs:string" use="required" />
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

问题是:

如何迭代(递归?)通过此架构中的所有元素?XmlSchemaSet 类如何存储它们?我需要将它们呈现给用户,以便他们可以进行一些映射.

How can I iterate (recursively?) through all the elements from this schema? How are they stored by the XmlSchemaSet class? I need to present them to the user so they can do some mapping.

我正在从 XmlSchemaSet.Schemas 属性中检索 XmlSchema,然后呢?XmlSchema.Elements 只包含一项(products),我找不到任何方法来查找它的子元素是什么.

I am retrieving an XmlSchema from XmlSchemaSet.Schemas property, and then what? XmlSchema.Elements only contains one item (products), and I can't find any way to look up what its subelements are.

推荐答案

好的!没有答案,也没有太大的兴趣——我自己想出来的.

Okay! No answer and not much interest - I figured it out on my own.

我使用了我在谷歌上搜索的这篇 MSDN 文章中的代码:遍历 XML 模式

I used code from this MSDN article I googled up: Traversing XML Schemas

我的递归解决方案就是以此为基础的.

And I based my recursive solution on it.

void PrintSchema(string xmlFilePath)
{
    var schemaSet = new XmlSchemaInference().InferSchema(XmlReader.Create(xmlFilePath));
    foreach (XmlSchemaElement element in schemaSet
        .Schemas()
        .Cast<XmlSchema>()
        .SelectMany(s => s.Elements.Values.Cast<XmlSchemaElement>()))
    {
        Debug.WriteLine(element.Name + " (element)");
        IterateOverElement(element.Name, element);
    }
}

void IterateOverElement(string root, XmlSchemaElement element)
{
    var complexType = element.ElementSchemaType as XmlSchemaComplexType;
    if (complexType == null) 
    {
        return;
    }
    if (complexType.AttributeUses.Count > 0)
    {
        var enumerator = complexType.AttributeUses.GetEnumerator();
        while (enumerator.MoveNext())
        {
            var attribute = (XmlSchemaAttribute)enumerator.Value;
            Debug.WriteLine(root + "." + attribute.Name + " (attribute)");
        }
    }
    var sequence = complexType.ContentTypeParticle as XmlSchemaSequence;
    if (sequence == null) 
    {
        return;
    }
    foreach (XmlSchemaElement childElement in sequence.Items)
    {
        root += String.Concat(".", childElement.Name);
        Debug.WriteLine(root + " (element)");
        // recursion
        IterateOverElement(root, childElement);
    }
}

输出为:

products (element)
products.product (element)
products.product.id (attribute)
products.product.name (attribute)
products.product.size (element)
products.product.size.name (attribute)
products.product.price (element)
products.product.price.net (element)
products.product.price.gross (element)

我让你来判断这个 API 的友好程度,特别是考虑到这些特定类的 MSDN 文档是多么稀缺.感谢您提出任何意见或见解.

I leave to you to judge how friendly this API is, especially given how scarce is the MSDN documentation on these particular classes. Any comments or insights are appreciated.

这篇关于从 XML 文件推断的 XmlSchema - 如何遍历 XSD 中的所有元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:如何在 c# .net CF 3.5 中使用 XmlDocument 向 xml 添加属性 下一篇:为什么 XSD.EXE 会创建两个 .XSD 文件,以及如何使用它们?

相关文章