Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用包含来自另一个命名空间的keyref的XSD创建XML实例_Xml_Namespaces_Xsd_Keyref - Fatal编程技术网

如何使用包含来自另一个命名空间的keyref的XSD创建XML实例

如何使用包含来自另一个命名空间的keyref的XSD创建XML实例,xml,namespaces,xsd,keyref,Xml,Namespaces,Xsd,Keyref,我试图验证一个依赖于另一个实例(来自不同名称空间)的XML实例,它在该名称空间中有一个键引用。当我尝试验证实例时,它会产生一个错误,表示密钥超出范围 这些是我的XSD: test1.xsd <?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="

我试图验证一个依赖于另一个实例(来自不同名称空间)的XML实例,它在该名称空间中有一个键引用。当我尝试验证实例时,它会产生一个错误,表示密钥超出范围

这些是我的XSD:

test1.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    targetNamespace="test1" xmlns="test1">

    <xs:complexType name="Host">
        <xs:attribute name="id" type="xs:string"/>
    </xs:complexType>
    <xs:element name="root">
        <xs:complexType>
            <xs:all>
                <xs:element name="hosts">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element maxOccurs="unbounded" minOccurs="0" name="host" type="Host"
                            />
                        </xs:sequence>
                    </xs:complexType>
                    <xs:key name="Host-PK">
                        <xs:selector xpath="host"/>
                        <xs:field xpath="@id"/>
                    </xs:key>
                </xs:element>
            </xs:all>
        </xs:complexType>
    </xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    targetNamespace="test2" xmlns="test2" xmlns:t1="test1">

    <xs:import namespace="test1" schemaLocation="test1.xsd"/>

    <xs:element name="root">
        <xs:complexType>
            <xs:all>
                <xs:element name="server">
                    <xs:complexType>
                        <xs:attribute name="host" type="xs:string"/>
                    </xs:complexType>
                </xs:element>
            </xs:all>
        </xs:complexType>
        <xs:keyref name="Host-FK" refer="t1:Host-PK">
            <xs:selector xpath="server"/>
            <xs:field xpath="@host"/>
        </xs:keyref>
    </xs:element>
</xs:schema>

test2.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    targetNamespace="test1" xmlns="test1">

    <xs:complexType name="Host">
        <xs:attribute name="id" type="xs:string"/>
    </xs:complexType>
    <xs:element name="root">
        <xs:complexType>
            <xs:all>
                <xs:element name="hosts">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element maxOccurs="unbounded" minOccurs="0" name="host" type="Host"
                            />
                        </xs:sequence>
                    </xs:complexType>
                    <xs:key name="Host-PK">
                        <xs:selector xpath="host"/>
                        <xs:field xpath="@id"/>
                    </xs:key>
                </xs:element>
            </xs:all>
        </xs:complexType>
    </xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    targetNamespace="test2" xmlns="test2" xmlns:t1="test1">

    <xs:import namespace="test1" schemaLocation="test1.xsd"/>

    <xs:element name="root">
        <xs:complexType>
            <xs:all>
                <xs:element name="server">
                    <xs:complexType>
                        <xs:attribute name="host" type="xs:string"/>
                    </xs:complexType>
                </xs:element>
            </xs:all>
        </xs:complexType>
        <xs:keyref name="Host-FK" refer="t1:Host-PK">
            <xs:selector xpath="server"/>
            <xs:field xpath="@host"/>
        </xs:keyref>
    </xs:element>
</xs:schema>

我的例子是:

test1.xml

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="test1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="test1 test1.xsd">
  <hosts>
    <host id="ABC"/>
    <host id="DEF"/>
  </hosts>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:t1="test1" xmlns="test2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="test2 test2.xsd">
 <server host="ABC"/>
</root>
<!DOCTYPE root [
   <!ENTITY test3 SYSTEM "test3.xml">
]>

<root xmlns="test1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="test1 test1.xsd">
    &test3;
</root>
<!DOCTYPE root [
   <!ENTITY test3 SYSTEM "test3.xml">
]>

<root xmlns:t1="test1" xmlns="test2" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="test2 test2.xsd">
    &test3;
    <server host="ABC"/>
</root>

test2.xml

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="test1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="test1 test1.xsd">
  <hosts>
    <host id="ABC"/>
    <host id="DEF"/>
  </hosts>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:t1="test1" xmlns="test2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="test2 test2.xsd">
 <server host="ABC"/>
</root>
<!DOCTYPE root [
   <!ENTITY test3 SYSTEM "test3.xml">
]>

<root xmlns="test1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="test1 test1.xsd">
    &test3;
</root>
<!DOCTYPE root [
   <!ENTITY test3 SYSTEM "test3.xml">
]>

<root xmlns:t1="test1" xmlns="test2" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="test2 test2.xsd">
    &test3;
    <server host="ABC"/>
</root>

服务器主机属性是主机ID的关键引用

架构验证期间,test2.xml文件引发以下错误:

错误:[Xerces]标识约束错误:keyref标识 约束“主机FK”是指超出范围的键或唯一键

我怎样才能解决这个问题


我如何从test2.xml引用test1.xml实例?

我假设您可以更改这两个XSD,并且您正在使用XSD 1.0

在第一个XSD中,您需要限定XPath元素,因为不固定的元素不属于任何名称空间。照目前情况,你的钥匙不起作用。您可以通过将重复ID添加到
test1
来验证这一点:

<root xmlns="test1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="test1 test1.xsd">
    <hosts>
        <host id="ABC"/>
        <host id="DEF"/>
        <host id="DEF"/>
    </hosts>
</root>
现在,您可以限定XPath表达式:

<xs:key name="Host-PK">
    <xs:selector xpath="t1:host"/>
    <xs:field xpath="@id"/>
</xs:key>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
           xmlns:t1="test1" targetNamespace="test2" 
           xmlns="test2" xmlns:t2="test2" >
我还将
minOccurs=“0”
添加到
hosts
中,这样就可以定义一个只包含服务器的
根目录(但这是临时的-我们将在完成之前再次要求它)

现在我们可以在
test2.xsd
中引用
hosts
元素和
Root
类型。我们可以从扩展
元素的基类型开始,以允许
服务器
元素:

<xs:complexType name="NewRoot">
    <xs:complexContent>
        <xs:extension base="t1:Root">
            <xs:sequence>
                <xs:element name="server">
                    <xs:complexType>
                        <xs:attribute name="host" type="xs:string"/>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:extension>
    </xs:complexContent>
</xs:complexType>
现在
test2
中的
root
元素是
test1
root
元素的扩展,而
host
元素将位于上下文中

由于必须使用XPath来选择服务器元素,因此有必要为
test2
的名称空间声明前缀,以便在XPath表达式中使用它:

<xs:key name="Host-PK">
    <xs:selector xpath="t1:host"/>
    <xs:field xpath="@id"/>
</xs:key>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
           xmlns:t1="test1" targetNamespace="test2" 
           xmlns="test2" xmlns:t2="test2" >
这是重构后的最后一个test2.xsd

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           elementFormDefault="qualified"
           targetNamespace="test1" 
           xmlns="test1" 
           xmlns:t1="test1">

    <xs:complexType name="Host">
        <xs:attribute name="id" type="xs:string"/>
    </xs:complexType>

    <xs:complexType name="Root">
        <xs:sequence>
            <xs:element ref="hosts" minOccurs="0"/>
        </xs:sequence>
    </xs:complexType>

    <xs:element name="root" type="Root" />

    <xs:element name="hosts">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" minOccurs="0" name="host" type="Host"/>
            </xs:sequence>
        </xs:complexType>
        <xs:key name="Host-PK">
            <xs:selector xpath="t1:host"/>
            <xs:field xpath="@id"/>
        </xs:key>
    </xs:element>

</xs:schema>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           elementFormDefault="qualified"
           targetNamespace="test2" 
           xmlns="test2" 
           xmlns:t2="test2" 
           xmlns:t1="test1">

    <xs:import namespace="test1" schemaLocation="test1.xsd"/>

    <xs:complexType name="NewRoot">
        <xs:complexContent>
            <xs:extension base="t1:Root">
                <xs:sequence>
                    <xs:element name="server">
                        <xs:complexType>
                            <xs:attribute name="host" type="xs:string"/>
                        </xs:complexType>
                    </xs:element>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:element name="root" type="t2:NewRoot">
        <xs:key name="Host-PK">
            <xs:selector xpath="t1:hosts/t1:host"/>
            <xs:field xpath="@id"/>
        </xs:key>
        <xs:keyref name="Host-FK" refer="Host-PK">
            <xs:selector xpath="t2:server"/>
            <xs:field xpath="@host"/>
        </xs:keyref>
    </xs:element>
</xs:schema>
你可以试试看。除非
host
ABC
DEF
,否则它不会验证

您可能还希望将
hosts
子树保存在一个单独的文件中,并将其导入到两个XML实例中。实现这一点的本机方法是声明DTD实体。首先将您的
主机
放入一个文件(test3.xml):

test2.xml

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns="test1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="test1 test1.xsd">
  <hosts>
    <host id="ABC"/>
    <host id="DEF"/>
  </hosts>
</root>
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:t1="test1" xmlns="test2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="test2 test2.xsd">
 <server host="ABC"/>
</root>
<!DOCTYPE root [
   <!ENTITY test3 SYSTEM "test3.xml">
]>

<root xmlns="test1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="test1 test1.xsd">
    &test3;
</root>
<!DOCTYPE root [
   <!ENTITY test3 SYSTEM "test3.xml">
]>

<root xmlns:t1="test1" xmlns="test2" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="test2 test2.xsd">
    &test3;
    <server host="ABC"/>
</root>

&测试3;

现在,您可以将
minOccurs=“0”
放回
test1.xsd中的
hosts
声明中,以确保它始终存在。

您可以更改父xsd吗?