如何让XSD Schema验证上面一个路径的唯一元素?

时间:2014-07-07 03:09:50

标签: xml xsd xml-validation

我有一个XSD架构,它查找唯一值,但只在一个路径下查找它,而不是在它上面的一个级别上唯一(查看XML文件,我的部分旁边的描述应该失败)

我的XML层次结构是:

Root: Root
..........Targets
..................Target
..........Packages
..................Package
.........................Dependencies
......................................BuildDependency
......................................................<RelativeSandboxPath> <---HAS TO BE UNIQUE

应该失败的XML文件:

<?xml version="1.0" encoding="utf-8"?>
<Root>
  <Version>1</Version>
  <ProjectName>aabc</ProjectName>
  <ProjectVersion>1.0</ProjectVersion>
  <Targets>
    <Target>
      <TargetName>foo</TargetName>
      <CommandLine>gcc bar</CommandLine>
      <BuildEnvTypeName>none</BuildEnvTypeName>
      <RelativeOutputPath>none</RelativeOutputPath>
      <RelativeLogPath>none</RelativeLogPath>
      <Dependencies/>
    </Target>
  </Targets>
  <Packages>
    <Package>
      <Dependencies>
        <BuildDependency>
          <ProjectName>foo</ProjectName>
          <ProjectVersion>1</ProjectVersion>
          <TargetName>bar</TargetName>
          <ProjectBuild>none</ProjectBuild> 
          <RelativeSandboxPath>Unique</RelativeSandboxPath> ***has to be unique under all /Dependencies***
          <RelativeSandboxPath>Unique</RelativeSandboxPath> ***if this was here (it's not), then the XML would fail***
        </BuildDependency>
        <BuildDependency>
          <ProjectName>bar</ProjectName>
          <ProjectVersion>3</ProjectVersion>
          <TargetName>foo</TargetName>
          <ProjectBuild>3</ProjectBuild> 
          <RelativeSandboxPath>Unique</RelativeSandboxPath> ***has to be unique under all /Dependencies***
        </BuildDependency>
      </Dependencies>
    </Package>
  </Packages>
</Root>

XSD架构:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:annotation>
    <xs:appinfo source="urn:schemas-microsoft-com:xml-msdatasource">
      <DataSource DefaultConnectionIndex="0" FunctionsComponentName="QueriesTableAdapter" Modifier="AutoLayout, AnsiClass, Class, Public" SchemaSerializationMode="IncludeSchema" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
        <Connections />
        <Tables />
        <Sources />
      </DataSource>
    </xs:appinfo>
  </xs:annotation>
  <xs:element name="Root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Version" type="xs:string" minOccurs="0" />
        <xs:element name="ProjectName" type="xs:string" minOccurs="0" />
        <xs:element name="ProjectVersion" type="xs:string" minOccurs="0" />
        <xs:element name="Targets" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Target" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="TargetName" type="xs:string" minOccurs="0" />
                    <xs:element name="CommandLine" type="xs:string" minOccurs="0" />
                    <xs:element name="BuildEnvTypeName" type="xs:string" minOccurs="0" />
                    <xs:element name="RelativeOutputPath" type="xs:string" minOccurs="0" />
                    <xs:element name="RelativeLogPath" type="xs:string" minOccurs="0" />
                    <xs:element name="Dependencies" type="xs:string" minOccurs="0" />
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="Packages" minOccurs="0" maxOccurs="unbounded">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Package" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="CommandLine" type="xs:string" minOccurs="0" />
                    <xs:element name="BuildEnvTypeName" type="xs:string" minOccurs="0" />
                    <xs:element name="PackageName" type="xs:string" minOccurs="0" />
                    <xs:element name="RelativeOutputPath" type="xs:string" minOccurs="0" />
                    <xs:element name="RelativeLogPath" type="xs:string" minOccurs="0" />
                    <xs:element name="Dependencies" minOccurs="0" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="BuildDependency" minOccurs="0" maxOccurs="unbounded">
                            <xs:complexType>
                              <xs:sequence>
                                <xs:element name="ProjectName" type="xs:string" minOccurs="0" />
                                <xs:element name="ProjectVersion" type="xs:string" minOccurs="0" />
                                <xs:element name="TargetName" type="xs:string" minOccurs="0" />
                                <xs:element name="ProjectBuild" type="xs:string" minOccurs="0" />
                                <xs:element name="RelativeSandboxPath" type="xs:string" minOccurs="0" />
                              </xs:sequence>
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="PBC" />
      </xs:choice>
    </xs:complexType>
    *******HERE*********
    <xs:unique name="BuildDependency_Constraint1" msdata:ConstraintName="Constraint1">
      <xs:selector xpath=".//BuildDependency" />
      <xs:field xpath="RelativeSandboxPath" />
    </xs:unique>
    *******HERE*********
  </xs:element>
</xs:schema>

2 个答案:

答案 0 :(得分:0)

我不确定你的问题究竟是什么。所以只是一些提示:

  1. 根据您提供的架构,“BuildDependenc”元素中不会出现两个“RelativeSandboxPath”元素。因此,您提供的XML示例将因此失败,而不是因为唯一约束。如果可能有多个“RelativeSandboxPath”元素,则应将<xs:element name="RelativeSandboxPath" type="xs:string" minOccurs="0"/>更改为<xs:element name="RelativeSandboxPath" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
  2. 元素“NewDataSet”未显示在您的XML以及它尝试引用的“PBC”元素中。它也不适合你在帖子中提到的结构。所以我不知道它的目的是什么。但是如果你想约束“BuildDependency”元素,你应该在“Dependencies”元素中声明这个约束,例如:

    <xs:element name="Dependencies" minOccurs="0" maxOccurs="unbounded">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="BuildDependency" minOccurs="0" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="ProjectName" type="xs:string" minOccurs="0"/>
                            <xs:element name="ProjectVersion" type="xs:string" minOccurs="0"/>
                            <xs:element name="TargetName" type="xs:string" minOccurs="0"/>
                            <xs:element name="ProjectBuild" type="xs:string" minOccurs="0"/>
                            <xs:element name="RelativeSandboxPath" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
        <xs:unique name="BuildDependency_Constraint1" msdata:ConstraintName="Constraint1">
            <xs:selector xpath=".//BuildDependency"/>
            <xs:field xpath="RelativeSandboxPath"/>
        </xs:unique>
    </xs:element>
    

答案 1 :(得分:0)

您没有非常清楚地解释您的要求。但是这是一种思考方式:如果你希望同一个A中的每个B都有一个C的唯一值,那么在A的元素声明中,定义一个xs:unique约束,其中选择器XPath从A中选择B,并且XPath字段从B中选择C.例如,如果一个Person的每个Child都应该有一个唯一的firstName,那么在Person中定义xs:unique与selector xpath =“Child”,field xpath =“firstName”。