最近为了验证一个xml文件的合法性,犹豫约束较多,包括数据类型、唯一约束,类似数据库外键的约束,如果这些都使用java代码去验证的话,显然会有很大的工作量,其次,如果xml文件发生变更,代码也会需要做很大的变更,所以,我首先想到的是使用xml schema 对文件进行验证,使用Altova.XMLSpy.Enterprise.2010编写完xsd文件,并用在该软件上使用刚编写完的xsd验证目标xml文件的结果非常完美。接着着手开始编写java代码:
import java.io.File; import javax.xml.XMLConstants; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.validation.Validator; import org.xml.sax.SAXException; public class Main { /** * @param args */ public static void main(String[] args) { File f=new File("E:/git/SkybilityHA/doc/cluster.xsd"); try { Source xmlFile = new StreamSource(new File("E:\\git\\SkybilityHA\\doc\\cluster.xml")); SchemaFactory schemaFactory = SchemaFactory .newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); Schema schema = schemaFactory.newSchema(f); Validator validator = schema.newValidator(); try { validator.validate(xmlFile); System.out.println(xmlFile.getSystemId() + " is valid"); } catch (SAXException e) { System.out.println(xmlFile.getSystemId() + " is NOT valid"); System.out.println("Reason: " + e.getLocalizedMessage()); } } catch (Exception e1) { e1.printStackTrace(); } } }
运行代码,问题出来了,结果验证有误,错误信息如下:
file:/E:/git/SkybilityHA/doc/cluster.xml is NOT valid
Reason: Key 'resourceBootorderFK' with value '28' not found for identity constraint of element 'resources'.
为什么两次验证结果不一致?是Altova.XMLSpy.Enterprise.2010错了,还是java错了,于是又找了一个在线验证网站(http://www.freeformatter.com/xml-validator-xsd.html)对结果进行验证,结果仍然是不通过。显然Altova.XMLSpy.Enterprise.2010的结果验证不正确。为了方便测试xsd,我又下载了Oxygen.XML.Editor.v15来进行xsd的编辑,xsd文件内容如下:
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <!-- 数据类型定义:IP--> <xsd:simpleType name="IP"> <xsd:restriction base="xsd:string"> <xsd:pattern value="(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])"/> </xsd:restriction> </xsd:simpleType> <!-- 数据类型定义:通讯协议--> <xsd:simpleType name="PROTOCOL"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="UDP"/> <xsd:enumeration value="TCP"/> </xsd:restriction> </xsd:simpleType> <!-- 数据类型定义:端口号--> <xsd:simpleType name="PORT"> <xsd:restriction base="xsd:int"> <xsd:minInclusive value="0"/> <xsd:maxInclusive value="65535"/> </xsd:restriction> </xsd:simpleType> <!-- 数据类型定义:整数--> <xsd:simpleType name="PLUS"> <xsd:restriction base="xsd:int"> <xsd:minInclusive value="0"/> </xsd:restriction> </xsd:simpleType> <!-- 数据类型定义:yes 或者 no--> <xsd:simpleType name="YON"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="yes"/> <xsd:enumeration value="no"/> </xsd:restriction> </xsd:simpleType> <!--##############################################################3daemons元素定义######################################################################--> <xsd:element name="daemons"> <xsd:complexType> <xsd:sequence> <xsd:element name="ha"> <xsd:complexType> <xsd:attribute name="no_quorum_policy" type="xsd:string"/> </xsd:complexType> </xsd:element> <xsd:element name="hacmm"> <xsd:complexType> <xsd:attribute name="tiebreaker" type="IP"/> </xsd:complexType> </xsd:element> <xsd:element name="halrmd"/> <xsd:element name="hadc"/> <xsd:element name="hatrap"> <xsd:complexType> <xsd:attribute name="timeout" type="PLUS"/> <xsd:attribute name="retries" type="PLUS"/> <xsd:attribute name="version" type="xsd:string"/> <xsd:attribute name="name" type="xsd:string"/> <xsd:attribute name="password" type="xsd:string"/> </xsd:complexType> </xsd:element> <xsd:element name="watchdog"> <xsd:complexType> <xsd:attribute name="margin" type="PLUS"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <!--#####################################################################nodes元素定义########################################################--> <xsd:element name="nodes"> <xsd:complexType> <xsd:sequence> <xsd:element name="node" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="id" type="PLUS" use="required"/> <xsd:attribute name="name" type="xsd:string" use="required"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <!--#####################################################################subnets定义#########################################################--> <xsd:element name="subnets"> <xsd:complexType> <xsd:sequence> <xsd:element name="subnet" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="node" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="id" use="required"/> <xsd:attribute name="host" type="IP" use="required"/> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="id" type="xsd:string" use="required"/> <xsd:attribute name="mcast_port" type="PORT"/> <xsd:attribute name="mcast_addr" type="IP"/> <xsd:attribute name="protocol" type="PROTOCOL"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <!--#####################################################################bootorders定义##########################################################--> <xsd:element name="bootorders"> <xsd:complexType> <xsd:sequence> <xsd:element name="bootorder" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="bootfirst" use="required"/> <xsd:attribute name="ignore_on_stop" type="YON"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <!--####################################################################locations定义#############################################################--> <xsd:element name="locations"> <xsd:complexType> <xsd:sequence> <xsd:element name="location" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="location_with" use="required"/> <xsd:attribute name="on_same_node" type="YON"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <!--#######################################################################resources定义###########################################################--> <xsd:element name="resources"> <xsd:complexType> <xsd:sequence> <xsd:element name="resource" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="parameter"> <xsd:complexType> <xsd:sequence> <xsd:element name="node" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="id" use="required"/> <xsd:attribute name="local_ip" type="IP"/> <xsd:attribute name="local_disk" type="xsd:string"/> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="type" type="xsd:string" use="required"/> <xsd:anyAttribute namespace="##any" processContents="skip"/> </xsd:complexType> </xsd:element> <xsd:element ref="bootorders"/> </xsd:sequence> <xsd:attribute name="id" type="PLUS" use="required"/> <xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="fail_strategy" type="xsd:string"/> <xsd:attribute name="on_stop_error" type="xsd:string"/> <xsd:attribute name="disabled" type="YON"/> <xsd:attribute name="check_status" type="YON"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> <!--定义资源的ID做为外键--> <xsd:key name="resourcePk"> <xsd:selector xpath="./resource"/> <xsd:field xpath="@id"/> </xsd:key> <!---资源启动顺序依赖的只能是当前服务下的资源--> <xsd:keyref name="resourceBootorderFK" refer="resourcePk"> <xsd:selector xpath="./resource/bootorders/bootorder"/> <xsd:field xpath="@bootfirst"/> </xsd:keyref> </xsd:element> <!--#######################################runnable_nodes定义:服务可运行节点,必须是在nodes 中定义了的node######################################--> <xsd:element name="runnable_nodes"> <xsd:complexType> <xsd:sequence> <xsd:element name="node" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:attribute name="id" use="required"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <!--###################################################################services定义##############################################################--> <xsd:element name="services"> <xsd:complexType> <xsd:sequence> <xsd:element name="service" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element ref="runnable_nodes"/> <xsd:element name="rules"/> <xsd:element name="groups"/> <xsd:element ref="bootorders"/> <xsd:element ref="locations"/> <xsd:element ref="resources"/> </xsd:sequence> <xsd:attribute name="id" type="PLUS" use="required"/> <xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="is_critical" type="YON"/> <xsd:attribute name="multi_running" type="PLUS"/> <xsd:attribute name="disabled" type="YON"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <!--#########################################################################fences定义#########################################################--> <xsd:element name="fences"> <xsd:complexType> <xsd:sequence> <xsd:element name="node" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="fencing_svc"> <xsd:complexType> <xsd:attribute name="id" use="required"/> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="id" use="required"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <!--########################################################################svc定义##########################################################--> <xsd:element name="svc"> <xsd:complexType> <xsd:attribute name="id" use="required"/> </xsd:complexType> </xsd:element> <!--###################################################################service_groups定义######################################################--> <xsd:element name="service_groups"> <xsd:complexType> <xsd:sequence> <xsd:element name="service_group" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="master"> <xsd:complexType> <xsd:sequence> <xsd:element ref="svc" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element> <xsd:element name="slave"> <xsd:complexType> <xsd:sequence> <xsd:element ref="svc" minOccurs="0" maxOccurs="unbounded"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> <xsd:attribute name="id" type="xsd:string" use="required"/> <xsd:attribute name="name" type="xsd:string" use="required"/> <xsd:attribute name="enable_always" type="YON"/> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> <!--###########################################################文档整体结构定义############################################################################--> <xsd:element name="cluconfig"> <xsd:complexType> <xsd:sequence> <xsd:element ref="daemons"/> <xsd:element ref="nodes"/> <xsd:element ref="subnets"/> <xsd:element ref="services"/> <xsd:element ref="fences"/> <xsd:element ref="service_groups"/> </xsd:sequence> <xsd:attribute name="service_sequence" type="PLUS" use="required"/> <xsd:attribute name="resource_sequence" type="PLUS" use="required"/> </xsd:complexType> <!--################################################################# node约束 #############################################################################--> <!--节点ID唯一--> <xsd:unique name="nodesNodeId"> <xsd:selector xpath="./nodes/node"/> <xsd:field xpath="@id"/> </xsd:unique> <!--节点名称唯一--> <xsd:unique name="nodesNodeName"> <xsd:selector xpath="./nodes/node"/> <xsd:field xpath="@name"/> </xsd:unique> <!--定义节点的ID做为外键--> <xsd:key name="nodesNodePk"> <xsd:selector xpath="./nodes/node"/> <xsd:field xpath="@id"/> </xsd:key> <!--################################################################# subnets约束 #############################################################################--> <!--定义子网的节点必须是在nodes中定义过的节点--> <xsd:keyref name="subnetsSubnetFK" refer="nodesNodePk"> <xsd:selector xpath="./subnets/subnet/node"/> <xsd:field xpath="@id"/> </xsd:keyref> <!--################################################################# services约束 #############################################################################--> <!--服务ID唯一--> <xsd:unique name="serviceId"> <xsd:selector xpath="./services/service"/> <xsd:field xpath="@id"/> </xsd:unique> <!--服务name唯一--> <xsd:unique name="serviceName"> <xsd:selector xpath="./services/service"/> <xsd:field xpath="@name"/> </xsd:unique> <!--定义服务的ID做为外键--> <xsd:key name="servicePk"> <xsd:selector xpath="./services/service"/> <xsd:field xpath="@id"/> </xsd:key> <!--服务可运行节点必须是在nodes中定义过的节点--> <xsd:keyref name="serviceRunnableNodeFK" refer="nodesNodePk"> <xsd:selector xpath="./services/service/runnable_nodes/node"/> <xsd:field xpath="@id"/> </xsd:keyref> <!--服务启动依赖的服务只能是已定义过的服务--> <xsd:keyref name="serviceBootorderFK" refer="servicePk"> <xsd:selector xpath="./services/service/bootorders/bootorder"/> <xsd:field xpath="@bootfirst"/> </xsd:keyref> <!--服务位置依赖的服务只能是已定义过的服务--> <xsd:keyref name="serviceLocationFK" refer="servicePk"> <xsd:selector xpath="./services/service/locations/location"/> <xsd:field xpath="@location_with"/> </xsd:keyref> <!--资源ID唯一--> <xsd:unique name="resourceId"> <xsd:selector xpath="./services/service/resources/resource"/> <xsd:field xpath="@id"/> </xsd:unique> <!--资源name唯一--> <xsd:unique name="resourceName"> <xsd:selector xpath="./services/service/resources/resource"/> <xsd:field xpath="@name"/> </xsd:unique> <!--service resources resource parameter node id必须是在nodes中定义过的节点--> <xsd:keyref name="resourceParamNodeFK" refer="nodesNodePk"> <xsd:selector xpath="./services/service/resources/resource/parameter/node"/> <xsd:field xpath="@id"/> </xsd:keyref> <!--################################################################# fences约束 #############################################################################--> <!--fence node id 唯一--> <xsd:unique name="fencesNodeId"> <xsd:selector xpath="./fences/node"/> <xsd:field xpath="@id"/> </xsd:unique> <!--fence node svc id 唯一--> <xsd:unique name="fencesNodeSvcId"> <xsd:selector xpath="./fences/node/fencing_svc"/> <xsd:field xpath="@id"/> </xsd:unique> <!--fence 下面的节点Id只能是已经定义了的节点--> <xsd:keyref name="fencesNodeFK" refer="nodesNodePk"> <xsd:selector xpath="./fences/node"/> <xsd:field xpath="@id"/> </xsd:keyref> <!--fence中节点下的服务只能是已定义过的服务--> <xsd:keyref name="fencesNodeSvcFK" refer="servicePk"> <xsd:selector xpath="./fences/node/fencing_svc"/> <xsd:field xpath="@id"/> </xsd:keyref> <!--############################################################## service_groups约束 #########################################################################--> <!--服务组ID唯一--> <xsd:unique name="serviceGroupId"> <xsd:selector xpath="./service_groups/service_group"/> <xsd:field xpath="@id"/> </xsd:unique> <!--服务组名称唯一--> <xsd:unique name="serviceGroupName"> <xsd:selector xpath="./service_groups/service_group"/> <xsd:field xpath="@name"/> </xsd:unique> <!--服务组下的服务只能是已定义过的服务--> <xsd:keyref name="serviceGroupsSvcFK" refer="servicePk"> <xsd:selector xpath="./service_groups/service_group/*/svc"/> <xsd:field xpath="@id"/> </xsd:keyref> <!--服务只能属于某一个服务组的某个角色一--> <xsd:unique name="serviceGroupsSvcPK"> <xsd:selector xpath="./service_groups/service_group/*/svc"/> <xsd:field xpath="@id"/> </xsd:unique> </xsd:element> </xsd:schema>
xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?> <cluconfig service_sequence="26" resource_sequence="59" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:/d:/t.xsd"> <daemons> <ha no_quorum_policy="fence"/> <hacmm tiebreaker="192.168.10.1"/> <halrmd/> <hadc/> <hatrap timeout="4" retries="1" version="2" name="" password=""/> <watchdog margin="30"/> </daemons> <nodes> <node id="1" name="ems01"/> <node id="2" name="ems02"/> <node id="4" name="abcdef"/> </nodes> <subnets> <subnet mcast_port="7301" mcast_addr="239.9.9.9" protocol="UDP" id="primary"> <node id="1" host="192.168.9.5"/> <node id="2" host="192.168.122.175"/> </subnet> <subnet id="secondary"> <node id="2" host="192.168.10.175"/> <node id="4" host="192.168.1.2"/> </subnet> </subnets> <services> <service id="10" name="ems_all_ora" is_critical="yes"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders> <bootorder bootfirst="5"/> <bootorder bootfirst="6"/> </bootorders> <locations/> <resources/> </service> <service id="16" name="ems_app" is_critical="yes"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders> <bootorder bootfirst="13"/> <bootorder bootfirst="10" ignore_on_stop="yes"/> </bootorders> <locations> <location location_with="10" on_same_node="no"/> </locations> <resources> <resource id="28" name="ems_ip" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="ip" nic="eth1" netmask="255.255.255.0" ip="192.168.122.200"/> <bootorders/> </resource> <resource id="29" name="ems_app" disabled="yes" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="app/generic2" status_script="/home/cluster/ems/monitor_aix.sh console1" stop_script="/home/cluster/ems/off-line.sh console1" start_script="/home/cluster/ems/start-console.sh console1" start_timeout="360" stop_timeout="360" online_code="110" offline_code="100"/> <bootorders> <bootorder bootfirst="28"/> </bootorders> </resource> </resources> </service> <service id="11" name="ems_drbd_config" multi_running="3"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders/> <locations/> <resources> <resource id="30" name="ems_drbd_config" fail_strategy="recovery_service" check_status="no" on_stop_error="retry"> <parameter type="storage/drbd/config" protocol="C" local_ip="192.168.10.200" local_disk="/dev/lower_ems_vg/lower_ems_lv" drbdX="drbd0" peer_ip="192.168.10.201"> <node id="1" local_ip="127.0.0.1"/> <node id="2" local_disk="/dev/aaa"/> </parameter> <bootorders/> </resource> <resource id="31" name="ems_ora_drbd_config" fail_strategy="recovery_service" check_status="no" on_stop_error="retry"> <parameter type="storage/drbd/config" local_ip="192.168.10.202" local_disk="/dev/lower_ora_vg/lower_ora_lv" drbdX="drbd1" peer_ip="192.168.10.203"/> <bootorders/> </resource> </resources> </service> <service id="12" name="ems_drbd_dev"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders/> <locations> <location location_with="13" on_same_node="yes"/> <location location_with="15" on_same_node="yes"/> </locations> <resources> <resource id="20" name="ems_drbd_ip" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="ip" netmask="255.255.255.0" ip="192.168.10.200"/> <bootorders/> </resource> <resource id="22" name="ems_lower_lv" fail_strategy="recovery_service"> <parameter type="storage/lvm" deactive="yes" device="/dev/lower_ems_vg/lower_ems_lv"/> <bootorders/> </resource> <resource id="23" name="ems_drbd_dev" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="storage/drbd/dev" resource="drbd0"/> <bootorders> <bootorder bootfirst="20"/> <bootorder bootfirst="22"/> </bootorders> </resource> </resources> </service> <service id="13" name="ems_drbd_pri"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders> <bootorder bootfirst="12"/> </bootorders> <locations> <location location_with="16" on_same_node="yes"/> </locations> <resources> <resource id="24" name="ems_drbd_pri" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="storage/drbd/primary" resource="drbd0"/> <bootorders/> </resource> <resource id="25" name="ems_lv" fail_strategy="recovery_service"> <parameter type="storage/lvm" deactive="yes" device="/dev/vg-drbd0/ems_lv"/> <bootorders> <bootorder bootfirst="24"/> </bootorders> </resource> <resource id="26" name="ems_fs" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="filesystem" fstype="ext4" mountoint="/omc" device="/dev/vg-drbd0/ems_lv"/> <bootorders> <bootorder bootfirst="25"/> </bootorders> </resource> </resources> </service> <service id="15" name="ems_drbd_sec"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders> <bootorder bootfirst="12"/> </bootorders> <locations/> <resources> <resource id="27" name="ems_drbd_sec" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="storage/drbd/secondary" resource="drbd0"/> <bootorders/> </resource> </resources> </service> <service id="5" name="ems_ora_app"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders> <bootorder bootfirst="2"/> <bootorder bootfirst="4"/> </bootorders> <locations> <location location_with="10" on_same_node="yes"/> </locations> <resources> <resource id="9" name="ems_ora_lsnr" disabled="yes" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="app/databases/oracle/lsnrctl" oracle_sid="ems" oracle_home="/oracle/app/oracle/product/11.2.0/dbhome_1" listener="LISTENER_EMS"/> <bootorders/> </resource> <resource id="10" name="ems_ora_inst" disabled="yes" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="app/databases/oracle/instance" oracle_sid="ems" oracle_home="/oracle/app/oracle/product/11.2.0/dbhome_1"/> <bootorders/> </resource> </resources> </service> <service id="1" name="ems_ora_drbd_dev"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders/> <locations> <location location_with="2" on_same_node="yes"/> <location location_with="3" on_same_node="yes"/> </locations> <resources> <resource id="0" name="ems_ora_drbd_ip" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="ip" netmask="255.255.255.0" ip="192.168.10.202"/> <bootorders/> </resource> <resource id="2" name="ems_lower_ora_lv" fail_strategy="recovery_service"> <parameter type="storage/lvm" deactive="yes" device="/dev/lower_ora_vg/lower_ora_lv"/> <bootorders/> </resource> <resource id="3" name="ems_ora_drbd_dev" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="storage/drbd/dev" resource="drbd1"/> <bootorders> <bootorder bootfirst="0"/> <bootorder bootfirst="2"/> </bootorders> </resource> </resources> </service> <service id="2" name="ems_ora_drbd_pri" disabled="yes"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders> <bootorder bootfirst="1"/> </bootorders> <locations> <location location_with="5" on_same_node="yes"/> </locations> <resources> <resource id="4" name="ems_ora_drbd_pri" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="storage/drbd/primary" resource="drbd1"/> <bootorders> <bootorder bootfirst="6"/> </bootorders> </resource> <resource id="5" name="ems_ora_lv" fail_strategy="recovery_service"> <parameter type="storage/lvm" deactive="yes" device="/dev/vg-drbd1/ora_lv"/> <bootorders> <bootorder bootfirst="4"/> </bootorders> </resource> <resource id="6" name="ems_ora_fs" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="filesystem" fstype="ext4" mountpoint="/oracledata" device="/dev/vg-drbd1/ora_lv"/> <bootorders> <bootorder bootfirst="5"/> </bootorders> </resource> </resources> </service> <service id="3" name="ems_ora_drbd_sec"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders> <bootorder bootfirst="1"/> </bootorders> <locations> <location location_with="4" on_same_node="yes"/> </locations> <resources> <resource id="7" name="ems_ora_drbd_sec" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="storage/drbd/secondary" resource="drbd1"/> <bootorders/> </resource> </resources> </service> <service id="4" name="ems_ora_ip"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders/> <locations> <location location_with="5" on_same_node="yes"/> <location location_with="6" on_same_node="yes"/> </locations> <resources> <resource id="8" name="ems_ora_ip" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="ip" nic="eth1" netmask="255.255.255.0" ip="192.168.122.202"/> <bootorders/> </resource> </resources> </service> <service id="6" name="ems_ora_pm_app"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders/> <locations> <location location_with="10" on_same_node="yes"/> </locations> <resources> <resource id="11" name="ems_pmdata_lv" fail_strategy="recovery_service"> <parameter type="storage/lvm" deactive="yes" device="/dev/pmdata_vg/pmdata_lv"/> <bootorders/> </resource> <resource id="12" name="ems_pmdata_fs" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="filesystem" fstype="ext4" mountpoint="/pmdatas" device="/dev/pmdata_vg/pmdata_lv"/> <bootorders> <bootorder bootfirst="11"/> </bootorders> </resource> <resource id="13" name="ems_ora_pm_lsnr" disabled="yes" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="app/databases/oracle/lsnrctl" oracle_sid="pm" oracle_home="/oracle/app/oracle/product/11.2.0/dbhome_1" listener="LISTENER_PM"/> <bootorders/> </resource> <resource id="14" name="ems_ora_pm_inst" disabled="yes" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="app/databases/oracle/instance" oracle_sid="pm" oracle_home="/oracle/app/oracle/product/11.2.0/dbhome_1"/> <bootorders> <bootorder bootfirst="12"/> </bootorders> </resource> </resources> </service> <service id="9" name="ems_pmtool"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders> <bootorder bootfirst="8"/> </bootorders> <locations> <location location_with="8" on_same_node="yes"/> </locations> <resources> <resource id="18" name="ems_pmtool_ip" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="ip" netmask="255.255.255.0" ip="192.168.10.204"/> <bootorders/> </resource> <resource id="19" name="ems_pmtool" disabled="yes" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="app/generic2" status_script="/pmsynctool/pmsynctool-cluster/monitor.sh" stop_script="/pmsynctool/pmsynctool-cluster/off-line.sh" start_script="/pmsynctool/pmsynctool-cluster/start.sh" online_code="110" offline_code="100"/> <bootorders> <bootorder bootfirst="18"/> </bootorders> </resource> </resources> </service> <service id="8" name="ems_pmtool_fs" multi_running="3"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders/> <locations/> <resources> <resource id="15" name="ems_ocfs" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="app/generic" script="/etc/init.d/o2cb"/> <bootorders/> </resource> <resource id="17" name="ems_pmtool_fs" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="filesystem" fstype="ocfs2" mountpoint="/pmsynctool" device="/dev/mapper/mpathh"/> <bootorders> <bootorder bootfirst="15"/> </bootorders> </resource> </resources> </service> <service id="21" name="fence_ems01" disabled="yes" multi_running="2"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders/> <locations/> <resources> <resource id="56" name="fence_ems01" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="fence/stonith/external/libvirt" start_timeout="20" stop_timeout="15" hostlist="SkybilityHA_cgsl_4" hypervisor_uri="qemu+ssh://192.168.10.7/system" status_timeout="20"/> <bootorders/> </resource> </resources> </service> <service id="22" name="fence_ems02" disabled="yes" multi_running="2"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders/> <locations/> <resources> <resource id="57" name="fence_ems02" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="fence/stonith/external/libvirt" start_timeout="20" stop_timeout="15" hostlist="SkybilityHA_cgsl_5" hypervisor_uri="qemu+ssh://192.168.10.7/system" status_timeout="20"/> <bootorders/> </resource> </resources> </service> <service id="23" name="fence_ems03" disabled="yes" multi_running="2"> <runnable_nodes/> <rules/> <groups/> <bootorders/> <locations/> <resources> <resource id="58" name="fence_ems03" fail_strategy="recovery_service"> <parameter type="fence/stonith/external/libvirt" start_timeout="20" stop_timeout="15" hostlist="SkybilityHA_cgsl_6" hypervisor_uri="qemu+ssh://192.168.10.7/system" status_timeout="20"/> <bootorders/> </resource> </resources> </service> <service id="24" name="monitor_business"> <runnable_nodes> <node id="3"/> </runnable_nodes> <rules/> <groups/> <bootorders/> <locations/> <resources> <resource id="54" name="ccm_ip" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="ip" netmask="255.255.255.0" ip="192.168.10.206"/> <bootorders/> </resource> <resource id="55" name="monitor_business" fail_strategy="recovery_service" on_stop_error="retry"> <parameter type="ccm" group_name="business" local_ip="192.168.10.206" remote_ip="192.168.10.207" tiebreaker="192.168.10.1" role="master" hbtimeout="60"/> <bootorders> <bootorder bootfirst="54"/> </bootorders> </resource> </resources> </service> </services> <fences> <node id="1"> <fencing_svc id="21"/> </node> <node id="2"> <fencing_svc id="22"/> </node> <node id="3"> <fencing_svc id="23"/> </node> </fences> <service_groups> <service_group id="0" name="global" enable_always="yes"> <master> <svc id="1"/> <svc id="4"/> <svc id="6"/> <svc id="8"/> <svc id="9"/> <svc id="12"/> <svc id="21"/> <svc id="22"/> <svc id="23"/> <svc id="24"/> </master> <slave/> </service_group> <service_group id="1" name="business"> <master> <svc id="2"/> <svc id="5"/> <svc id="10"/> <svc id="13"/> <svc id="16"/> </master> <slave> <svc id="3"/> <svc id="15"/> </slave> </service_group> <service_group id="2" name="config"> <master> <svc id="11"/> </master> <slave/> </service_group> </service_groups> </cluconfig>
最初以为是下面一段代码中的selector元素的xpath不正确:
<!--定义节点的ID做为外键--> <xsd:key name="nodesNodePk"> <xsd:selector xpath="./nodes/node"/> <xsd:field xpath="@id"/> </xsd:key> <!--################################################################# subnets约束 #############################################################################--> <!--定义子网的节点必须是在nodes中定义过的节点--> <xsd:keyref name="subnetsSubnetFK" refer="nodesNodePk"> <xsd:selector xpath="./subnets/subnet/node"/> <xsd:field xpath="@id"/> </xsd:keyref>
可是几经验证,xpath是没有问题的,于是求助谷歌,查了一个晚上加一个上午,终于看到了这一段:
The first error I get on this is that you've constrained "Type" to be
singles or doubles, but the actual value is "Those are football matches".
The next error appears to be because the values you are using for keys have
variable numbers of leading and trailing spaces. If you want these
normalized, don't use the type xs:string.
The next two errors are because your key definitions and references don't
match: your Member elements are matching the content of the Name element,
not the @id attribute, and the Team elements are matching on the @Name
attribute, not the @id attribute.
It always helps, incidentally, to say which product you are using. Then you
might get someone looking at it who is familiar with the error messages
produced by that product.
英语不是很好,看的懵懵懂懂的,但是 don't use the type xs:string.这句话给了我一个提醒,我在定义nodes下的node的id属性时使用了type=“PLUS”这个我自定义的数据类型,而在subnets下的subnet下的node的id中却没有使用type定义属性值的类型,这会导致验证时把它的值当作xs:string或者其他什么基本类型来处理,反正不会是PLUS类型,这就导致了虽然值看起来一样,但是因为类型不一样,而不能找到引用的值而验证错误。如果也为该id设置type=“PLUS”,问题完美解决。
Michael Kay