- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个包含多个复杂类型和简单类型的 XSD(文件的一部分如下所示)。我需要解析此文档以从复杂类型中引用的每个简单类型中获取 maxLength。任何人都可以就如何实现这个提出一些建议吗?我需要以通用方式实现它,所以如果我查询“Setup_Type”,它应该给出以下输出。谢谢!
NewSetup/Amount = 12(由“/”分隔的元素标签的名称属性和嵌套 simpleType 的 maxLength)
新设置/名称 = 50
<xsd:complexType name="Setup_Type">
<xsd:sequence>
<xsd:element name="NewSetup" type="NewSetup_Type" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="NewSetup_Type">
<xsd:sequence>
<xsd:element name="Amount" type="Amount_Type" minOccurs="1" maxOccurs="1" />
<xsd:element name="Name" type="Name_Type" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
<xsd:simpleType name="Amount_Type">
<xsd:annotation>
<xsd:documentation>Amount</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="12" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="Name_Type">
<xsd:annotation>
<xsd:documentation>Name</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="50" />
</xsd:restriction>
</xsd:simpleType>
最佳答案
我在过去看到过类似的问题(完全公开,我自己也问过类似的问题 question)。解析 XSD 不适合胆小的人。
您基本上有 2 个选项,第一个更容易实现,但可以通过对 XSD 进行较小的更改来更容易地破坏。第二个更强大但难以实现。
选项 1:
使用 LINQ(如果您愿意,也可以使用其他 C# XML 解析器)解析 XSD。由于 XSD 只是一个 XML,您可以将其加载到 XDocument
中并通过 LINQ 读取它。
您自己的 XSD 示例:
<xsd:simpleType name="Amount_Type">
<xsd:annotation>
<xsd:documentation>Amount</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="12" />
</xsd:restriction>
</xsd:simpleType>
您可以访问 MaxLength:
var xDoc = XDocument.Load("your XSD path");
var ns = XNamespace.Get(@"http://www.w3.org/2001/XMLSchema");
var length = (from sType in xDoc.Element(ns + "schema").Elements(ns + "simpleType")
where sType.Attribute("name").Value == "Amount_Type"
from r in sType.Elements(ns + "restriction")
select r.Element(ns + "maxLength").Attribute("value")
.Value).FirstOrDefault();
这并没有提供一种非常简单的方法来按类型名称进行解析,尤其是对于扩展类型。要使用它,您需要知道要查找的每个元素的确切路径。
选项 2:
这太复杂了,无法快速回答(注意:请参阅下面的编辑 - 我花了一些时间整理了一个可行的解决方案),所以我鼓励您看看我的我在上面链接的自己的问题。在其中,我链接了一个 great blog它显示了如何认真地将 XSD 分解成多个部分,并可能允许您执行所需的搜索类型。您必须决定开发它是否值得(该博客显示了使用 XmlReader
的实现,其中包含针对相关 XSD 进行验证的 XML,但您可以通过直接加载来轻松完成此操作XSD 并对其进行解析。
在博客中找到的 2 个关键想法是:
// in the getRestriction method (reader in this context is an `XmlReader` that
// contains a XML that is being validated against the specific XSD
if (reader.SchemaInfo.SchemaElement == null) return null;
simpleType = reader.SchemaInfo.SchemaElement.ElementSchemaType as XmlSchemaSimpleType;
if (simpleType == null) return null;
restriction = simpleType.Content as XmlSchemaSimpleTypeRestriction;
// then in the getMaxLength method
if (restriction == null) return null;
List<int> result = new List<int>();
foreach (XmlSchemaObject facet in restriction.Facets) {
if (facet is XmlSchemaMaxLengthFacet) result.Add(int.Parse(((XmlSchemaFacet) facet).Value));
去年我实际上尝试过同样的事情来解析 XSD 作为复杂数据验证方法的一部分。我花了一周的大部分时间才真正了解发生了什么,并根据我的目的调整博客中的方法。这绝对是实现您想要的东西的最佳方式。
如果您想尝试使用独立模式,您可以将 XSD 加载到 XmlSchemaSet
对象中,然后使用 GlobalTypes
属性来帮助您找到特定类型你正在寻找。
编辑:我提取了我的旧代码并开始整理这些代码来帮助您。
首先加载您的架构:
XmlSchemaSet set; // this needs to be accessible to the methods below,
// so should be a class level field or property
using (var fs = new FileStream(@"your path here", FileMode.Open)
{
var schema = XmlSchema.Read(fs, null);
set = new XmlSchemaSet();
set.Add(schema);
set.Compile();
}
根据您提供的 XSD,以下方法应该可以让您接近您想要的结果。它应该非常适合处理更复杂的结构。
public Dictionary<string, int> GetElementMaxLength(String xsdElementName)
{
if (xsdElementName == null) throw new ArgumentException();
// if your XSD has a target namespace, you need to replace null with the namespace name
var qname = new XmlQualifiedName(xsdElementName, null);
// find the type you want in the XmlSchemaSet
var parentType = set.GlobalTypes[qname];
// call GetAllMaxLength with the parentType as parameter
var results = GetAllMaxLength(parentType);
return results;
}
private Dictionary<string, int> GetAllMaxLength(XmlSchemaObject obj)
{
Dictionary<string, int> dict = new Dictionary<string, int>();
// do some type checking on the XmlSchemaObject
if (obj is XmlSchemaSimpleType)
{
// if it is a simple type, then call GetMaxLength to get the MaxLength restriction
var st = obj as XmlSchemaSimpleType;
dict[st.QualifiedName.Name] = GetMaxLength(st);
}
else if (obj is XmlSchemaComplexType)
{
// if obj is a complexType, cast the particle type to a sequence
// and iterate the sequence
// warning - this will fail if it is not a sequence, so you might need
// to make some adjustments if you have something other than a xs:sequence
var ct = obj as XmlSchemaComplexType;
var seq = ct.ContentTypeParticle as XmlSchemaSequence;
foreach (var item in seq.Items)
{
// item will be an XmlSchemaObject, so just call this same method
// with item as the parameter to parse it out
var rng = GetAllMaxLength(item);
// add the results to the dictionary
foreach (var kvp in rng)
{
dict[kvp.Key] = kvp.Value;
}
}
}
else if (obj is XmlSchemaElement)
{
// if obj is an XmlSchemaElement, the you need to find the type
// based on the SchemaTypeName property. This is why your
// XmlSchemaSet needs to have class-level scope
var ele = obj as XmlSchemaElement;
var type = set.GlobalTypes[ele.SchemaTypeName];
// once you have the type, call this method again and get the dictionary result
var rng = GetAllMaxLength(type);
// put the results in this dictionary. The difference here is the dictionary
// key is put in the format you specified
foreach (var kvp in rng)
{
dict[String.Format("{0}/{1}", ele.QualifiedName.Name, kvp.Key)] = kvp.Value;
}
}
return dict;
}
private Int32 GetMaxLength(XmlSchemaSimpleType xsdSimpleType)
{
// get the content of the simple type
var restriction = xsdSimpleType.Content as XmlSchemaSimpleTypeRestriction;
// if it is null, then there are no restrictions and return -1 as a marker value
if (restriction == null) return -1;
Int32 result = -1;
// iterate the facets in the restrictions, look for a MaxLengthFacet and parse the value
foreach (XmlSchemaObject facet in restriction.Facets)
{
if (facet is XmlSchemaMaxLengthFacet)
{
result = int.Parse(((XmlSchemaFacet)facet).Value);
break;
}
}
return result;
}
那么用法就很简单了,你只需要调用 GetElementMaxLength(String)
方法,它就会返回你提供的格式的名字字典,最大长度为值:
var results = GetElementMaxLength("Setup_Type");
foreach (var item in results)
{
Console.WriteLine("{0} | {1}", item.Key, item.Value);
}
关于c# - 如何解析 XSD 以从 <xsd :simpleType> elements using C#? 获取信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11569264/
我有一个可以是任何字符串的属性,但如果它有开始和结束括号“^[.*]$” - 它必须只是以下特定值之一: "[EVENT]" 和 "[PROTOCOL]" 因此,"[EVENT]"、"[PROTOC
我想编写一个方法,它确实返回 PrimitiveType 的某些内容,例如 float 、整数、 boolean 值,如果可能的话还返回字符串。我想使用泛型,但我卡住了,没有找到解决方案。我确实需要它
我正在解析我的 XSD 文件。 (包括一些元素,complexTypes和simpleTypes) 我想通过类型属性检测它们中的每一个。 我的 XSD 文件有点像这样。
我正在尝试选择序列中其实现类型的元素名称为 xs:simpleType 的所有子元素。
想象在 definition.xsd 中有一个已定义的简单类型 那么该类型在2个不同的xsds中使用:use1.xsd和use2.xsd: use1.xsd:
我正在使用 xjc 将一组 XSD 编译为 Java 类。我希望能够覆盖给定简单类型的数据类型定义。 XSD 片段是: Can be specified as a inte
现在我有一个看起来像这样的 XSD 文件(例如 FOO_SCHEMA.xsd): Comment
我正在尝试重用已经编译并可用的类。这看起来可以通过按照下面的示例绑定(bind)摘录声明对预先存在的类的绑定(bind)来实现:-
我有一种情况,我有不同的 XML,这些 XML 具有不同类型的属性。有时,元素 HEADER 可能只有一个节点,或者某些 XML 可能在 HEADER 节点中包含元素,并在其中包含值。 示例 1(HE
在编译基于 java 的语言 - 处理之前,我需要预处理一些代码。在这种语言中,所有类型 color 的实例都需要替换为 int。例如,这是一个代码片段: color red = 0xffaabbcc
我在 XSD 架构中有一个字段: 在java类中生成了一个字段: int magicField; 但随后,xsd
我正在尝试创建一个 XML 架构,它可以将属性值存储为 native 格式的 GUID。我可以将其设置为字符串,但最好将其存储为真正的 GUID。 有什么想法吗? 最佳答案 您可以通过使用如下正则表达
在我的 XML 模式定义中,我试图将属性的值限制为 0 到 100 之间的整数。 引用下面的示例架构,我希望元素“root”上的属性“attr”具有此限制。 为了实现这一点,我定义了一个 simple
我正在尝试使用正则表达式为表中的列添加时间验证。首先我添加了一栏,请找到下面的代码: oTableFileContents.addColumn( new sap.ui.table.Column
我需要将一些 XML(似乎是 XML 复杂结构)转换为 C# 数据集。 所以起初我尝试使用以下方法从 XSD 创建数据集结构: ds.ReadXml(@"D:\data_RUIAN\ruian\xsd
假设我正在处理一个 xsd:simpleType,它是一个字符串,需要具有特定的字符集和特定的最大长度,类似于以下代码: 所以我的 xsd 类型将是一个只
我有一个这样的 xsd 文件:
我正在尝试使用 jaxb 和 spring 生成 JAVA 代码,但是当我有一个包含 2 个具有相同名称但位于不同命名空间的 simpleType 的 wsdl 文件时,我无法让它工作。有谁知道我该如
当我们在 simpleType 中指定名称参数时,我们得到一个错误: "s4s-att-not-allowed: Attribute 'name' cannot appear in element '
我有一个包含多个复杂类型和简单类型的 XSD(文件的一部分如下所示)。我需要解析此文档以从复杂类型中引用的每个简单类型中获取 maxLength。任何人都可以就如何实现这个提出一些建议吗?我需要以通用
我是一名优秀的程序员,十分优秀!