我在尝试从XSD扩展复杂类型时遇到了问题。关键是这个 - 我试图实现的复杂类型是在命名空间中,同样的命名空间被设置为父级的targetNamespace
。
这是父XSD(相关部分)
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://schemas.mandiant.com/2010/ioc"
elementFormDefault="qualified"
targetNamespace="http://schemas.mandiant.com/2010/ioc"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="ioc" nillable="true"
type="tns:IndicatorOfCompromise" />
<xs:complexType name="IndicatorOfCompromise">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1"
name="short_description" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1"
name="description" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1"
name="keywords" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1"
name="authored_by" type="xs:string" />
<xs:element minOccurs="1" maxOccurs="1"
name="authored_date" nillable="true"
type="xs:dateTime" />
<xs:element minOccurs="0" maxOccurs="1"
name="links" type="tns:ArrayOfLink" />
<xs:element minOccurs="0" maxOccurs="1"
name="definition" type="tns:ArrayOfIocIndicator" />
</xs:sequence>
<xs:attribute name="id" type="xs:string" />
<xs:attribute name="last-modified" type="xs:dateTime"
use="required" />
</xs:complexType>
</xs:schema>
这就是我试图扩展(基本上添加更多元素)的方式
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://schemas.mandiant.com/2010/ioc" >
<xs:import namespace="urn:tns"
schemaLocation="openioc_schema_v10.xsd" />
<xs:redefine schemaLocation="openioc_schema_v10.xsd">
<xs:complexType name="IndicatorOfCompromise">
<xs:complexContent>
<xs:extension base="tns:IndicatorOfCompromise">
<xs:sequence>
<xs:element name="category" type="xs:string" />
<xs:element name="family" type="xs:string" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
</xs:schema>
当我尝试针对此架构验证以下XML时,
<?xml version='1.0' encoding='UTF-8'?>
<ioc xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://schemas.mandiant.com/2010/ioc"
id="2555192b-186b-441d-bbdd-1d2fb41f462f"
last-modified="2016-05-12T12:14:50"
xmlns:qioc_v10="ioc_qualys_v10.xsd"
xsi:schemaLocation="ioc_qualys_v10.xsd">
<short_description>Bagsu!rfn</short_description>
<description>This is a placeholder for description of the Bagsu!rfn malware family.</description>
<keywords/>
<authored_by>IOC_api</authored_by>
<authored_date>2016-05-12T12:14:50</authored_date>
<qioc_v10:category>XYZ</qioc_v10:category>
<qioc_v10:family>XYZ 2</qioc_v10:family>
<links/>
</ioc>
它给出错误“元素信息项的名称空间属性'urn:tns'必须与导入文档的targetNamespace属性”http://schemas.mandiant.com/2010/ioc“相同。”
如何去做?我已经浏览了几篇Stackoverflow帖子,但似乎没有解决我的难题。我已经理解了我需要扩展的元素驻留在命名空间中而不知道如何解决它的问题。
请注意,我无法以任何方式触摸父xsd。这是OpenIOC标准。
答案 0 :(得分:3)
您可能想要了解XSD导入,包含,重新定义和(对于XSD 1.1)覆盖的基础知识。这将减少你必须做的猜测量。
在这种情况下,您的本地修改有几个问题,都与您不得不猜测该做什么有关,而不是清楚地了解架构间文档引用的含义。
首先,import语句与您建议导入的架构文档不兼容。您显示的本地架构包含:
<xs:import namespace="urn:tns"
schemaLocation="openioc_schema_v10.xsd" />
这意味着&#34;这里声明的组件可以引用命名空间urn的模式组件:tns;可以在openioc_schema_v10.xsd找到该命名空间的模式文档。&#34;但是,如果架构处理器接受您的提示并尝试读取openioc_schema_v10.xsd,则会发现其目标命名空间为http://schemas.mandiant.com/2010/ioc,而不是urn:tns。它不可能为命名空间urn:tns声明任何组件,因此它无法在命名空间urn:tns的导入的schemaLocation属性中有用地命名。
当然,您可以通过在import语句中指定正确的命名空间来解决此问题:
<xs:import namespace="http://schemas.mandiant.com/2010/ioc"
schemaLocation="openioc_schema_v10.xsd" />
如果执行此操作,您将收到一条新的不同错误消息,因为您正在尝试导入目标命名空间的架构。正如&#34; import&#34;普通英语是指将外国商品引入国内市场,因此&#34; import&#34;在XSD中意味着从其他(外部)名称空间引入模式组件。您无法导入目标命名空间的架构。这就是xsd:include的用途。
如果您将导入更改为包含,您可能会或可能不会获得引发错误消息的架构,但您不会获得可在整个实现中可靠运行的架构,因为现在您已包括openioc_schema_v10.xsd(通过include)的(未更改的)版本,包括它的修改版本(通过重新定义)。
你最好完全取消导入 - 应该是一个包含。重新定义openioc_schema_v10.xsd中定义的模式将引入该模式的所有模式组件,并具有重新定义所指定的修改。
如果删除了错误且不必要的导入,您会发现类型为IndicatorOfCompromise的声明指定了tns的基本类型:IndicatorOfCompromise,但现在在架构文档中,您将命名空间前缀tns绑定到任何命名空间。你想要
xmlns:tns="http://schemas.mandiant.com/2010/ioc"
在xs:extension元素或祖先。
这些是乍看之下可见的机械问题;可能会有更多。正如我所说:找一个好的教程,阅读它,学习包含,导入,重新定义和覆盖的基础知识。
另一件事:如果您正在扩展一个公开定义的类型,那么很可能您应该在自己的命名空间中定义新类型,而不是通过重新定义某人拥有的命名空间中的类型其他。但那会让我们走得太远。祝你好运。