notepad++ XML Validation 和 C# XMLDocument.validate 之间的不同结果

问题描述 投票:0回答:1

我正在尝试使用 XSD 对两个元素之间的属性组合强制执行唯一性约束。该约束在 Notepad++ 中工作正常,但在我的 C# 应用程序中工作不正常。

我已将以下独特的声明添加到我的 XSD 中:

<xs:unique name="uniqueEMNameParentID">
    <xs:selector xpath=".//EM"/>
    <xs:field xpath="@Name"/>
    <xs:field xpath=".//Station/@ID"/>
</xs:unique>

这是我的 XML 示例:

<?xml version="1.0" encoding="utf-8"?>
<Project>
  <PLC Name="PLC">
    <Type>
      <TypeDef ID="1" Name="G05" Description="" />
    </Type>
    <SA ID="01">
      <Station ID="100">
        <EM ID="01" Name="IR01" IsRobot="TRUE">          
        </EM>
      </Station>
    </SA>
    <SA ID="02">
      <Station ID="100">
        <EM ID="02" Name="IR01" IsRobot="TRUE">
        </EM>
        <EM ID="03" Name="IR03" IsRobot="TRUE">      
        </EM>
      </Station>
    </SA>
  </PLC>
</Project>

使用 Notepad++ 时,XSD 给出正确的错误:“IR01 是唯一身份约束‘uniqueEMNameParentID’的重复键。”但是,当使用以下代码在 C# 中针对 XSD 验证相同的 XML 时,不会报告错误:

 private void ValidateXML()
 {
     XmlSchemaSet schema = new XmlSchemaSet();
     schema.Add("", @"Z:\VMshare\Maarten\WindowsFormsApplication3\WindowsFormsApplication3\XML\XSDScheme3.xsd");
     projectXML.Schemas.Add(schema);

     projectXML.Validate((object sender, System.Xml.Schema.ValidationEventArgs args) =>
     {
         MessageBox.Show(args.Message);
     });
 }

我的 XML 文档不包含任何命名空间,我的 XSD 不包含目标命名空间,并且 attribute 和 elementformdefault 都设置为非限定。有谁知道它可能是什么?

请注意,我的 XML 有两个属性 ID=100 的 Station 元素。这些元素都有一个子元素 EM,其属性名称 = IR01。这应该是不可能的。

完整的XSD:

<xs:schema attributeFormDefault="qualified" elementFormDefault="unqualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Project">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="PLC">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Type">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="TypeDef">
                                            <xs:complexType>
                                                <xs:simpleContent>
                                                    <xs:extension base="xs:string">
                                                        <xs:attribute type="xs:byte" name="ID"/>
                                                        <xs:attribute type="xs:string" name="Name"/>
                                                        <xs:attribute type="xs:string" name="Description"/>
                                                    </xs:extension>
                                                </xs:simpleContent>
                                            </xs:complexType>
                                        </xs:element>
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="SA" maxOccurs="unbounded" minOccurs="0">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="Station" maxOccurs="unbounded" minOccurs="0">
                                            <xs:complexType>
                                                <xs:sequence>
                                                    <xs:element name="EM" maxOccurs="unbounded" minOccurs="0">
                                                        <xs:complexType>
                                                            <xs:sequence>
                                                                <xs:element name="Robot">
                                                                    <xs:complexType>
                                                                        <xs:sequence>
                                                                            <xs:element name="Jobs">
                                                                                <xs:complexType>
                                                                                    <xs:sequence>
                                                                                        <xs:element name="Job" maxOccurs="unbounded" minOccurs="0">
                                                                                            <xs:complexType>
                                                                                                <xs:simpleContent>
                                                                                                    <xs:extension base="xs:string">
                                                                                                        <xs:attribute type="xs:byte" name="ID" use="required"/>
                                                                                                        <xs:attribute type="xs:string" name="Description" use="required"/>
                                                                                                        <xs:attribute type="xs:string" name="Type" use="optional"/>
                                                                                                    </xs:extension>
                                                                                                </xs:simpleContent>
                                                                                            </xs:complexType>
                                                                                        </xs:element>
                                                                                    </xs:sequence>
                                                                                </xs:complexType>
                                                                            </xs:element>
                                                                            <xs:element name="Areas">
                                                                                <xs:complexType>
                                                                                    <xs:sequence>
                                                                                        <xs:element name="Area" maxOccurs="unbounded" minOccurs="0">
                                                                                            <xs:complexType>
                                                                                                <xs:simpleContent>
                                                                                                    <xs:extension base="xs:string">
                                                                                                        <xs:attribute type="xs:byte" name="ID" use="required"/>
                                                                                                        <xs:attribute type="xs:string" name="Description" use="required"/>
                                                                                                        <xs:attribute type="xs:string" name="TargetEM_No" use="optional"/>
                                                                                                    </xs:extension>
                                                                                                </xs:simpleContent>
                                                                                            </xs:complexType>
                                                                                        </xs:element>
                                                                                    </xs:sequence>
                                                                                </xs:complexType>
                                                                            </xs:element>
                                                                            <xs:element name="Userbits">
                                                                                <xs:complexType mixed="true">
                                                                                    <xs:sequence>
                                                                                        <xs:element name="Userbit" maxOccurs="unbounded" minOccurs="0">
                                                                                            <xs:complexType mixed="true">
                                                                                                <xs:sequence>
                                                                                                    <xs:element name="Reference" maxOccurs="unbounded" minOccurs="0">
                                                                                                        <xs:complexType>
                                                                                                            <xs:simpleContent>
                                                                                                                <xs:extension base="xs:string">
                                                                                                                    <xs:attribute type="xs:byte" name="Area" use="optional"/>
                                                                                                                    <xs:attribute type="xs:byte" name="Job" use="optional"/>
                                                                                                                </xs:extension>
                                                                                                            </xs:simpleContent>
                                                                                                        </xs:complexType>
                                                                                                    </xs:element>
                                                                                                </xs:sequence>
                                                                                                <xs:attribute type="xs:byte" name="ID" use="required"/>
                                                                                                <xs:attribute type="xs:string" name="Description" use="required"/>
                                                                                            </xs:complexType>
                                                                                        </xs:element>
                                                                                    </xs:sequence>
                                                                                </xs:complexType>
                                                                            </xs:element>
                                                                            <xs:element name="FZones">
                                                                                <xs:complexType mixed="true">
                                                                                    <xs:sequence>
                                                                                        <xs:element name="FZone" minOccurs="0">
                                                                                            <xs:complexType>
                                                                                                <xs:simpleContent>
                                                                                                    <xs:extension base="xs:string">
                                                                                                        <xs:attribute type="xs:byte" name="ID" use="optional"/>
                                                                                                        <xs:attribute type="xs:string" name="Function" use="optional"/>
                                                                                                    </xs:extension>
                                                                                                </xs:simpleContent>
                                                                                            </xs:complexType>
                                                                                        </xs:element>
                                                                                    </xs:sequence>
                                                                                </xs:complexType>
                                                                            </xs:element>
                                                                            <xs:element name="Programs">
                                                                                <xs:complexType>
                                                                                    <xs:sequence>
                                                                                        <xs:element name="Program" maxOccurs="unbounded" minOccurs="0">
                                                                                            <xs:complexType>
                                                                                                <xs:simpleContent>
                                                                                                    <xs:extension base="xs:string">
                                                                                                        <xs:attribute type="xs:byte" name="ID" use="required"/>
                                                                                                        <xs:attribute type="xs:string" name="JobSequence" use="required"/>
                                                                                                        <xs:attribute type="xs:byte" name="Home" use="required"/>
                                                                                                        <xs:attribute type="xs:string" name="Sheet" use="required"/>
                                                                                                    </xs:extension>
                                                                                                </xs:simpleContent>
                                                                                            </xs:complexType>
                                                                                        </xs:element>
                                                                                    </xs:sequence>
                                                                                </xs:complexType>
                                                                            </xs:element>
                                                                            <xs:element name="Tools">
                                                                                <xs:complexType>
                                                                                    <xs:sequence>
                                                                                        <xs:element name="Tool" maxOccurs="unbounded" minOccurs="0">
                                                                                            <xs:complexType>
                                                                                                <xs:simpleContent>
                                                                                                    <xs:extension base="xs:string">
                                                                                                        <xs:attribute type="xs:byte" name="ID" use="required"/>
                                                                                                        <xs:attribute type="xs:string" name="Type" use="required"/>
                                                                                                        <xs:attribute type="xs:string" name="Name" use="required"/>
                                                                                                    </xs:extension>
                                                                                                </xs:simpleContent>
                                                                                            </xs:complexType>
                                                                                        </xs:element>
                                                                                    </xs:sequence>
                                                                                </xs:complexType>
                                                                            </xs:element>
                                                                            <xs:element name="UserNumbers">
                                                                                <xs:complexType>
                                                                                    <xs:simpleContent>
                                                                                        <xs:extension base="xs:string">
                                                                                            <xs:attribute type="xs:string" name="NumberRequired" use="required"/>
                                                                                        </xs:extension>
                                                                                    </xs:simpleContent>
                                                                                </xs:complexType>
                                                                            </xs:element>
                                                                        </xs:sequence>
                                                                        <xs:attribute type="xs:string" name="Name" use="optional"/>
                                                                        <xs:attribute type="xs:string" name="Manufacturer" use="optional"/>
                                                                        <xs:attribute type="xs:byte" name="RobotIndex" use="optional"/>
                                                                    </xs:complexType>
                                                                </xs:element>
                                                                <xs:element name="TypePlaceholder" minOccurs="0">
                                                                    <xs:complexType>
                                                                        <xs:simpleContent>
                                                                            <xs:extension base="xs:string">
                                                                                <xs:attribute type="xs:string" name="Name"/>
                                                                            </xs:extension>
                                                                        </xs:simpleContent>
                                                                    </xs:complexType>
                                                                </xs:element>
                                                            </xs:sequence>
                                                            <xs:attribute type="xs:byte" name="ID" use="required"/>
                                                            <xs:attribute type="xs:string" name="Name" use="required"/>
                                                            <xs:attribute type="xs:string" name="IsRobot" use="required"/>
                                                        </xs:complexType>
                                                    </xs:element>
                                                </xs:sequence>
                                                <xs:attribute type="xs:short" name="ID" use="optional"/>
                                            </xs:complexType>

                                        </xs:element>
                                    </xs:sequence>
                                    <xs:attribute type="xs:byte" name="ID" use="optional"/>
                                </xs:complexType>

                            </xs:element>
                        </xs:sequence>
                        <xs:attribute type="xs:string" name="Name"/>
                    </xs:complexType>
                </xs:element>
                <xs:element name="ImportDocuments">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="HandshakeDocument" maxOccurs="unbounded" minOccurs="0">
                                <xs:complexType>
                                    <xs:simpleContent>
                                        <xs:extension base="xs:string">
                                            <xs:attribute type="xs:string" name="Name" use="required"/>
                                            <xs:attribute type="xs:string" name="ImportDate" use="required"/>
                                        </xs:extension>
                                    </xs:simpleContent>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
        <xs:unique name="uniqueEMNameParentID">
            <xs:selector xpath=".//EM"/>
            <xs:field xpath="@Name"/>
            <xs:field xpath=".//Station/@ID"/>
        </xs:unique>
    </xs:element>
</xs:schema>

完整的 XML

<?xml version="1.0" encoding="utf-8"?>
<Project>
  <PLC Name="PLC">
    <Type>
      <TypeDef ID="1" Name="G05" Description="" />
    </Type>
    <SA ID="01">
      <Station ID="100">
        <EM ID="01" Name="IR01" IsRobot="TRUE">
          <Robot Name="AR01" Manufacturer="FANUC" RobotIndex="1">
            <Jobs>
              <Job ID="1" Description="Handling Step 1" Type="" />
              <Job ID="2" Description="Handling Step 2" Type="" />
              <Job ID="3" Description="Handling Step 3" Type="" />
              <Job ID="4" Description="Handling Step 4" Type="" />
              <Job ID="5" Description="Handling Step 5" Type="" />
              <Job ID="6" Description="Handling Step 6" Type="" />
            </Jobs>
            <Areas>
              <Area ID="1" Description="100TP01" TargetEM_No="" />
              <Area ID="2" Description="100FR02-FX01" TargetEM_No="" />
            </Areas>
            <Userbits>
              <Userbit ID="1" Description="Userbit1: Pick_Action">
                <Reference Area="2" Job="5" />
              </Userbit>
              <Userbit ID="2" Description="Userbit2: Drop_Action">
                <Reference Area="1" Job="1" />
                <Reference Area="1" Job="2" />
                <Reference Area="1" Job="3" />
                <Reference Area="3" Job="4" />
                <Reference Area="3" Job="6" />
              </Userbit>
              <Userbit ID="30" Description="xx_Mute_Sensors">
                <Reference Area="1" Job="1" />
                <Reference Area="2" Job="1" />
                <Reference Area="2" Job="2" />
                <Reference Area="1" Job="2" />
                <Reference Area="2" Job="3" />
                <Reference Area="1" Job="3" />
                <Reference Area="3" Job="4" />
                <Reference Area="2" Job="5" />
                <Reference Area="3" Job="6" />
              </Userbit>
              <Userbit ID="31" Description="xx_Type_Transfer">
                <Reference Area="2" Job="1" />
                <Reference Area="1" Job="1" />
                <Reference Area="1" Job="2" />
                <Reference Area="1" Job="3" />
                <Reference Area="2" Job="3" />
                <Reference Area="3" Job="4" />
                <Reference Area="2" Job="5" />
                <Reference Area="3" Job="6" />
              </Userbit>
            </Userbits>
            <FZones />
            <Programs>
              <Program ID="1" JobSequence="1;2;3;4;5;6;" Home="1" Sheet="FA01++100+IR01_P1" />
              <Program ID="2" JobSequence="2;3;4;5;6;" Home="1" Sheet="FA01++100+IR01_P1" />
              <Program ID="3" JobSequence="3;4;5;6;" Home="1" Sheet="FA01++100+IR01_P1" />
              <Program ID="4" JobSequence="4;5;6;" Home="1" Sheet="FA01++100+IR01_P1" />
              <Program ID="5" JobSequence="5;6;" Home="1" Sheet="FA01++100+IR01_P1" />
              <Program ID="6" JobSequence="6;" Home="1" Sheet="FA01++100+IR01_P1" />
            </Programs>
            <Tools>
              <Tool ID="1" Type="spotweld gun" Name="FG01" />
              <Tool ID="2" Type="adhesive gun" Name="FG02" />
            </Tools>
            <UserNumbers NumberRequired="True" />
          </Robot>
          <TypePlaceholder Name="" />
        </EM>
      </Station>
    </SA>
    <SA ID="02">
      <Station ID="100">
        <EM ID="02" Name="IR01" IsRobot="TRUE">
          <Robot Name="AR02" Manufacturer="FANUC" RobotIndex="2">
            <Jobs>
              <Job ID="1" Description="Handling Step 1" Type="" />
              <Job ID="2" Description="Handling Step 2" Type="" />
              <Job ID="3" Description="Handling Step 3" Type="" />
              <Job ID="4" Description="Handling Step 4" Type="" />
              <Job ID="5" Description="Handling Step 5" Type="" />
              <Area/>
            </Jobs>
            <Areas>
              <Area ID="1" Description="100TP02" TargetEM_No="" />
              <Area ID="2" Description="100FR01-FX01" TargetEM_No="" />
              <Area ID="3" Description="100FX01" TargetEM_No="" />
            </Areas>
            <Userbits>
              <Userbit ID="1" Description="Userbit1: Pick_Action">
                <Reference Area="2" Job="4" />
              </Userbit>
              <Userbit ID="2" Description="Userbit2: Drop_Action">
                <Reference Area="1" Job="1" />
                <Reference Area="1" Job="2" />
                <Reference Area="2" Job="3" />
              </Userbit>
              <Userbit ID="30" Description="xx_Mute_Sensors">
                <Reference Area="2" Job="1" />
                <Reference Area="1" Job="1" />
                <Reference Area="1" Job="2" />
                <Reference Area="2" Job="2" />
                <Reference Area="2" Job="3" />
                <Reference Area="2" Job="4" />
                <Reference Area="3" Job="5" />
              </Userbit>
              <Userbit ID="31" Description="xx_Type_Transfer">
                <Reference Area="2" Job="1" />
                <Reference Area="1" Job="1" />
                <Reference Area="1" Job="2" />
                <Reference Area="2" Job="2" />
                <Reference Area="2" Job="3" />
                <Reference Area="2" Job="4" />
                <Reference Area="3" Job="5" />
              </Userbit>
            </Userbits>
            <FZones />
            <Programs>
              <Program ID="1" JobSequence="1;2;3;4;5;" Home="1" Sheet="FA01++100+IR02_P1" />
              <Program ID="2" JobSequence="2;3;4;5;" Home="1" Sheet="FA01++100+IR02_P1" />
              <Program ID="3" JobSequence="3;4;5;" Home="1" Sheet="FA01++100+IR02_P1" />
              <Program ID="4" JobSequence="4;5;" Home="1" Sheet="FA01++100+IR02_P1" />
              <Program ID="5" JobSequence="5;" Home="1" Sheet="FA01++100+IR02_P1" />
            </Programs>
            <Tools>
              <Tool ID="1" Type="gripper" Name="FG01" />
            </Tools>
            <UserNumbers NumberRequired="True" />
          </Robot>
          <TypePlaceholder Name="Type" />
        </EM>
        <EM ID="03" Name="IR03" IsRobot="TRUE">
          <Robot Name="AR03" Manufacturer="FANUC" RobotIndex="3">
            <Jobs>
              <Job ID="1" Description="Tackweld Step 1" Type="" />
              <Job ID="2" Description="Tackweld Step 2" Type="" />
              <Job ID="3" Description="Tackweld Step 3" Type="" />
              <Job ID="4" Description="Tackweld Step 4" Type="" />
              <Job ID="5" Description="Tackweld Step 5" Type="" />
              <Job ID="6" Description="Tackweld Step 6" Type="" />
              <Job ID="7" Description="Tackweld Step7" Type="" />
            </Jobs>
            <Areas>
              <Area ID="1" Description="100FR01-FX01" TargetEM_No="" />
              <Area ID="2" Description="100FR02-FX01" TargetEM_No="" />
            </Areas>
            <Userbits />
            <FZones />
            <Programs>
              <Program ID="1" JobSequence="1;2;3;4;5;6;7;" Home="1" Sheet="FA01++100+IR03_P1" />
              <Program ID="2" JobSequence="2;3;4;5;6;7;" Home="1" Sheet="FA01++100+IR03_P1" />
              <Program ID="3" JobSequence="3;4;5;6;7;" Home="1" Sheet="FA01++100+IR03_P1" />
              <Program ID="4" JobSequence="4;5;6;7;" Home="1" Sheet="FA01++100+IR03_P1" />
              <Program ID="5" JobSequence="5;6;7;" Home="1" Sheet="FA01++100+IR03_P1" />
              <Program ID="6" JobSequence="6;7;" Home="1" Sheet="FA01++100+IR03_P1" />
              <Program ID="7" JobSequence="7;" Home="1" Sheet="FA01++100+IR03_P1" />
            </Programs>
            <Tools>
              <Tool ID="1" Type="spotweld gun" Name="GW01" />
            </Tools>
            <UserNumbers NumberRequired="False" />
          </Robot>
        </EM>
      </Station>
    </SA>
  </PLC>
  <ImportDocuments>
    <HandshakeDocument Name="DO30011_FA01_Robot_PLC_Handshake_v6" ImportDate="18/04/2024" />
  </ImportDocuments>
</Project>
c# xml xsd notepad++
1个回答
0
投票

我不知道为什么模式处理器之间存在差异,但我确实注意到,在唯一性约束中,从

<xs:field xpath=".//Station/@ID"/>
元素开始时,字段
EM
永远不会选择任何内容,因此它可能不会执行任何操作你是故意的。

我认为XSD 1.0中的规则是,当其中一个字段没有选择任何内容时,则认为满足唯一性约束。然而,在这个领域,模式处理器并不总是 100% 一致。

© www.soinside.com 2019 - 2024. All rights reserved.