我有一个XML文件,我在运行时使用XmlSchemaInference
类推断其XSD架构。
示例文件:
<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>
它确实有效 - 它可以很好地推断出架构:
<?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
类存储的?我需要将它们呈现给用户,以便他们可以进行一些映射。
我正在从XmlSchema
属性中检索XmlSchemaSet.Schemas
,然后是什么? XmlSchema.Elements
只包含一个项目(products
),我找不到任何方法来查找其子元素。
答案 0 :(得分:17)
好!没有答案也没有太多兴趣 - 我自己想出来了。
我使用了这篇MSDN文章中的代码,我用Google搜索:Traversing XML Schemas
我将我的递归解决方案基于它。
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文档在这些特定类上的稀缺程度。任何意见或见解都表示赞赏。