问题描述
我有一个 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 中的所有元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!