题
对 XSD 能力的又一挑战,
我的客户一直在发送 XML 文件,这些文件将具有 0 个或多个未定义或 [调用] 意外标签(可能出现在层次结构中)。好吧,它们对我来说是多余的标签..所以我必须忽略它们的存在,但与它们一起还有一些需要验证的标签。
这是一个示例 XML:
<root>
<undefined_1>one</undefined_1>
<undefined_2>two</undefined_2>
<node>to_be_validated</node>
<undefined_3>two</undefined_3>
<undefined_4>two</undefined_4>
</root>
我尝试过的 XSD:
<xs:element name="root" type="root"></xs:element>
<xs:complexType name="root">
<xs:sequence>
<xs:any maxOccurs="2" minOccurs="0"/>
<xs:element name="node" type="xs:string"/>
<xs:any maxOccurs="2" minOccurs="0"/>
</xs:sequence>
</xs:complexType
由于某些原因,XSD 不允许这样做。
上面提到的例子只是一个示例。实用的 XML 带有 XML 标签的复杂层次结构..
如果您能破解它,请告诉我。
顺便说一句,替代解决方案是在验证过程之前插入 XSL 转换。好吧,我正在避免它,因为我需要更改触发验证过程的 .Net 代码,这至少得到我的公司的支持。
解决方案 2
结论:
这是不可能的XSD。所有我试图达到要求的方法被命名为“暧昧”通过验证的工具,伴随着一堆错误。
其他提示
在您的情况尚未有这一点,你可以尝试以下操作:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root" type="root"></xs:element>
<xs:complexType name="root">
<xs:sequence>
<xs:any maxOccurs="2" minOccurs="0" processContents="skip"/>
<xs:element name="node" type="xs:string"/>
<xs:any maxOccurs="2" minOccurs="0" processContents="skip"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
在Linux下能正常工作使用的libxml xmllint版本20706。
也许它可以使用名称空间:
<xs:element name="root" type="root"></xs:element>
<xs:complexType name="root">
<xs:sequence>
<xs:any maxOccurs="2" minOccurs="0" namespace="http://ns1.com" />
<xs:element name="node" type="xs:string"/>
<xs:any maxOccurs="2" minOccurs="0" namespace="http://ns2.com"/>
</xs:sequence>
</xs:complexType>
这将可能验证。
我遇到了同样的问题。
因为我从 .NET 调用了验证;我决定抑制特定的验证错误 ValidationEventHandler
作为解决方法。这对我有用。
private void ValidationEventHandler(object sender, ValidationEventArgs e)
{
switch (e.Severity)
{
case XmlSeverityType.Warning:
// Processing warnings
break;
case XmlSeverityType.Error:
if (IgnoreUnknownTags
&& e.Exception is XmlSchemaValidationException
&& new Regex(
@"The element '.*' has invalid child element '.*'\."
+ @" List of possible elements expected:'.*'\.")
.IsMatch(e.Exception.Message))
{
return;
}
// Processing errors
break;
default:
throw new InvalidEnumArgumentException("Severity should be one of the valid values");
}
}
重要的是 Thread.CurrentUICulture
必须设置为英语或 CultureInfo.InvariantCulture
当前线程才能正常工作。
你可以使用一个新的功能在XML1.1所谓的"开放式的内容"。总之,可以指定这额外的"未知"的元素可以加入一个复杂的类型在各个岗位和什么样的分析程序应该做的,如果它撞到任何这些元素
使用XML1.1,你的复杂类型将成为:
<xs:element name="root" type="root" />
<xs:complexType name="root">
<xs:openContent mode="interleave">
<xs:any namespace="##any" processContents="skip"/>
</xs:openContent>
<xs:sequence>
<xs:element name="node" type="xs:string"/>
</xs:sequence>
</xs:complexType>
如果你有很多复杂的类型,也可以设置一种"默认"开放内容模式的顶部你的架构:
<xs:schema ...>
<xs:defaultOpenContent mode="interleave">
<xs:any namespace="##any" processContents="skip"/>
</xs:defaultOpenContent>
...
</xs:schema>
W3C的规范内容开放的,可以发现在 http://www.w3.org/TR/xmlschema11-1/#oc 还有一个很好的书面记录的在这 http://www.ibm.com/developerworks/library/x-xml11pt3/#N102BA.
不幸的是,.净不支持XML1.1为的但我找不到任何免费XML1.1处理器-但几个付费的选项是: