代码之家  ›  专栏  ›  技术社区  ›  schoetbi

分层节点结构中的xsd:keyref

  •  0
  • schoetbi  · 技术社区  · 14 年前

    我尝试使用xsd:keyref从节点/子节点结构中引用到XML根元素的子级全局表。

    下面是一个XML示例

    <?xml version="1.0" encoding="UTF-8"?>
    <Root xmlns="http://www.example.org/keyTest"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.example.org/keyTest keyTest.xsd">
    
    <Globals key="key1"/>   
    <Globals key="key2"/>
    <Globals key="key3"/>
    
    <Node>
    <SubNode keyref="key2"/>
    <SubNode keyref="key3"/>    
    <SubNode keyref="key1">
        <SubNode keyref="key2">
            <SubNode keyref="key1"/>
        </SubNode>  
    </SubNode>      
    </Node>
    </Root>
    

    我还拥有一个定义文档中xsd:key和xsd:keyref字段的xsd。这些键应该在XML文档开始时验证所有keyref值都在全局表中。到目前为止,我还没有弄清楚选择器xpath表达式可能有什么问题。

    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" 
            targetNamespace="http://www.example.org/keyTest" 
            xmlns:tns="http://www.example.org/keyTest" 
            elementFormDefault="qualified">
    
    <complexType name="Global">
        <attribute name="key" type="string"/>
    </complexType>
    
    <complexType name="Node" >
        <sequence maxOccurs="unbounded">
            <element name="SubNode" type="tns:Node" minOccurs="0"/>
        </sequence>
        <attribute name="keyref" type="string"/>
    </complexType>
    
    <complexType name="Root">
        <sequence>
            <element name="Globals" type="tns:Global" maxOccurs="unbounded"/>
            <element name="Node" type="tns:Node" maxOccurs="1"/>
        </sequence>
    </complexType>
    
    <element name="Root" type="tns:Root">
        <key name="key">
            <selector xpath="Global"/>
            <field xpath="@key"></field>
        </key>
        <keyref name="keyref" refer="tns:key">
            <selector xpath="//SubNode"/>
            <field xpath="@keyref"/>
        </keyref>
    </element>
    

    问题是无法编译“//子节点”的xmllint问题

    keyTest.xsd:30: element selector: Schemas parser error :
           Element '{http://www.w3.org/2001/XMLSchema}selector', at
           atribute 'xpath': The XPath expression '//SubNode' could not be compiled.
           WXS schema keyTest.xsd failed to compile
    

    当我用一个xpath验证器来尝试xpath表达式时,它会按照w3c标准中的定义选择文档中的所有子节点,那么为什么这个xpath不能在选择器表达式中工作呢?

    我也试过了。//子节点。这编译正确,但如果我输入了错误的keyref,不会验证失败。

    1 回复  |  直到 14 年前
        1
  •  2
  •   schoetbi    14 年前

    我喜欢分享我找到的解决方案。

    正确的xsd与此类似,缺少命名空间:

    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" 
            targetNamespace="http://www.example.org/keyTest"   
            xmlns:tns="http://www.example.org/keyTest" 
            elementFormDefault="qualified">
    
    <complexType name="Global">
        <attribute name="key" type="string"/>
    </complexType>
    
    <complexType name="Node" >
        <sequence maxOccurs="unbounded">
            <element name="SubNode" type="tns:Node" minOccurs="0"/>
        </sequence>
        <attribute name="keyref" type="string"/>
    </complexType>
    
    <complexType name="Root">
        <sequence>
            <element name="Globals" type="tns:Global" maxOccurs="unbounded"/>
            <element name="Node" type="tns:Node" maxOccurs="1"/>
        </sequence>
    </complexType>
    
    <element name="Root" type="tns:Root">
        <key name="key">
            <selector xpath=".//tns:Globals"/>
            <field xpath="@key"></field>
        </key>
        <keyref name="keyref" refer="tns:key">
            <selector xpath=".//tns:SubNode"/>
            <field xpath="@keyref"/>
        </keyref>
        <unique name="uniqKey">
            <selector xpath=".//tns:Globals"/>
            <field xpath="@key"/>
        </unique>
    </element>
    

    多亏有人开始做这件事。