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代码,至少我的公司支持。
答案 0 :(得分:4)
如果您尚未完成此操作,可以尝试以下操作:
<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版本20706可以正常使用xmllint。
答案 1 :(得分:3)
结论:
XSD无法做到这一点。我试图达到要求的所有方法都被验证工具命名为“含糊不清”,伴随着一堆错误。
答案 2 :(得分:1)
也许它可以使用命名空间:
<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>
这可能会验证。
答案 3 :(得分:1)
我遇到了同样的问题。
因为我从.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
以使当前线程正常工作。
答案 4 :(得分:1)
您可以在XML 1.1中使用名为&#34; Open Content&#34;的新功能。简而言之,允许您指定其他&#34;未知&#34;元素可以添加到不同位置的复杂类型中,以及解析器在遇到任何元素时应该做什么
使用XML 1.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>
如果你有很多复杂的类型,你也可以设置一个&#34;默认&#34;在架构顶部打开内容模式:
<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处有一个很好的写法。
不幸的是,.NET不支持XML 1.1,但我无法找到任何免费的XML 1.1处理器 - 但是有几个付费选项: