2012-10-31 38 views
2

我有下面的XML:使用XSD验证XML元素

<?xml version="1.0" encoding="utf-8"?> 
<MainElement> 
    <id>1</id> 
    <name>John</name> 
    <custom> 
     <age>43</age> 
     <sex>male</sex> 
    </custom> 
</MainElement> 

而另一个XML文件:

<?xml version="1.0" encoding="utf-8"?> 
<MainElement> 
    <id>2</id> 
    <name>Dave</name> 
    <custom> 
     <age>51</age> 
     <county>England</country> 
     <city>London</city> 
    </custom> 
</MainElement> 

两个XML文件的主要结构是同一只<custom>元素具有不同实现。我已经有了一个XSD文件来检查“id”和“name”元素,其中<custom>元素的类型为xs:anyType。是否可以创建另一个XSD文件,该文件只验证<custom>元素而不查看所有其他存在的元素?

+0

你必须回答的第一件事是如何要弄清楚你应该得到哪个'custom'元素。如果您打算使用相同的标签但使用不同的内容模型,则无法在XSD 1.0中执行此操作,而无需自定义预处理XML并动态加载相应的XSD(称为悬空定义),或者使用附加到自定义元素的xsi:type属性。如果通过“自定义”元素表示任何命名元素,事情会变得更容易或更复杂,这取决于你想要的约束。如果你可以把更多的细节... –

+0

自定义元素将始终具有名称'自定义',是一个可选元素。例如,有三个客户会将XML文件发送给我,根据客户的需要,我需要使用相应的XSD文件来验证'custom'元素中的所有子元素。对于所有三个客户,我将使用相同的XSD来验证xml文件的其余部分,如'id'和'name'元素。任何想法,如果这可以完成与XSD的唯一或我需要使用其他技术? – JustRonald

回答

0

我会向两位顾客说明。第一个XSD是应该捕获所有通用部分的基础部分,除了我们引用但未定义的custom之外;我们把它留下来“摇晃”。

下面是common.xsd:

<?xml version="1.0" encoding="utf-8"?> 
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)--> 
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <xsd:element name="MainElement"> 
    <xsd:complexType> 
     <xsd:sequence> 
     <xsd:element name="id" type="xsd:unsignedByte" /> 
     <xsd:element name="name" type="xsd:string" /> 
     <xsd:element ref="custom"/> 
     </xsd:sequence> 
    </xsd:complexType> 
    </xsd:element> 
</xsd:schema> 

然后我们开始定义一个XSD每个custom。对于第一个XML(定制1.xsd):

<?xml version="1.0" encoding="utf-8"?> 
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)--> 
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <xsd:element name="custom"> 
     <xsd:complexType> 
      <xsd:sequence> 
       <xsd:element name="age" type="xsd:unsignedShort"/> 
       <xsd:element name="sex" type="xsd:string"/> 
      </xsd:sequence> 
     </xsd:complexType> 
    </xsd:element> 
</xsd:schema> 

而对于第二个,定制2.xsd:

<?xml version="1.0" encoding="utf-8"?> 
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)--> 
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <xsd:element name="custom"> 
     <xsd:complexType> 
      <xsd:sequence> 
       <xsd:element name="age" type="xsd:unsignedShort"/> 
       <xsd:element name="country" type="xsd:string"/> 
       <xsd:element name="city" type="xsd:string"/> 
      </xsd:sequence> 
     </xsd:complexType> 
    </xsd:element> 
</xsd:schema> 

那么你必须要为每个客户创建一个模式集适当地装载的XSD:第一组将包括公共+定制-1,然后共同+定制-2等

这是我将如何使用“可视化”这些组QTAssistant:

enter image description here

当然,Common本身无效。

Error occurred while loading [file:///.../validate-xml-element-with-xsd-2.xsd], line 9 position 10. 
The 'custom' element is not declared. 

然而,对方的收集是有效的,因为在一组额外的XSD使进入活动范围缺失的定义。现在您可以验证每个供应商的XML及其关联的集合。您保持供应商通用定义的完整性,因为您确实共享了一个共同的XSD,并且您在XSD 1.0中使用了悬而未决的定义可以避开“限制”。我认为这不是一个限制;这可能是一种“不太优雅”的方法......

从处理角度来看,您会承担与您拥有的供应商一样多次编译和加载常见XSD(s)的开销。

如果这成为一种负担,您也可以使用另一种策略,一旦预处理您的XML返回回报。您可以将custom定义为anyType,甚至将其替换为xsd:any。一旦验证了常用的功能,您就可以提取节点(XSLT或DOM API或DOM节点阅读器之上的验证阅读器等),并使用适当的XSD独立验证它。

后面方法的优点是您不会有任何XSD方面的开销。当然,交易可能会增加处理的占地面积。

XSD 1.1,XSD 1.0 + Schematron,RelaxNG是涉及另一种模式语言的解决方案,它们各有优缺点。我认为上面应该至少可以帮助你理解你的一些选择......

0

有了XSD,你不能用字面意思去任何!

所以你需要声明所有来作为XML的一部分。在这种或那种方式等..

我给竖起大拇指您使用导入的方法/包括..这是一个干净,并允许进一步扩展的要求..但你仍然应该知道的任何元素的可能的名称..

虽然它不是必需的,你会intested知道使用Sequencechoice的另一种方法,只有达到您的要求,ONE XSD

这里是代码,这既证明了XML1和XML2:

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="MainElement"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="id" type="xs:unsignedByte" /> 
     <xs:element name="name" type="xs:string" /> 
     <xs:element name="custom"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:choice> 
       <xs:element name="age" type="xs:unsignedByte" /> 
       </xs:choice> 
       <xs:choice> 
       <xs:sequence> 
        <xs:element name="sex" type="xs:string" /> 
       </xs:sequence> 
       <xs:sequence> 
        <xs:element name="country" type="xs:string"/> 
        <xs:element name="city" type="xs:string"/> 
       </xs:sequence> 
       </xs:choice> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

这可能不是现在对您有用,但可能在未来..