【问题标题】:s4s-att-invalid-value: Invalid attribute value for 'name' in element 'element's4s-att-invalid-value:元素“元素”中“名称”的属性值无效
【发布时间】:2017-02-20 18:00:35
【问题描述】:

XML

<ns2:Response xmlns:ns2="http://test.com/" Id="122212">
  <Infos size="1">
     <Info>
        <name>test</name>
     </Info>
  </Infos>
</ns2:Response>

生成的 XSD

 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
     <!-- XML Schema Generated from XML Document on Mon Feb 20 2017 23:20:03 GMT+0530 (India Standard Time) -->
     <!-- with XmlGrid.net Free Online Service http://xmlgrid.net -->
     <xs:element name="ns2:Response">
           <xs:complexType>
                 <xs:sequence>
                       <xs:element name="Infos">
                             <xs:complexType>
                                   <xs:sequence>
                                         <xs:element name="Info">
                                               <xs:complexType>
                                                     <xs:sequence>
                                                           <xs:element name="name" type="xs:string"></xs:element>
                                                     </xs:sequence>
                                               </xs:complexType>
                                         </xs:element>
                                   </xs:sequence>
                                   <xs:attribute name="size" type="xs:int"></xs:attribute>
                             </xs:complexType>
                       </xs:element>
                 </xs:sequence>
                 <xs:attribute name="xmlns:ns2" type="xs:string"></xs:attribute>
                 <xs:attribute name="Id" type="xs:int"></xs:attribute>
           </xs:complexType>
     </xs:element>

错误

SAX 异常:s4s-att-invalid-value:属性值无效 元素“元素”中的“名称”。记录原因: cvc-datatype-valid.1.2.1:“ns2:响应”不是有效值 'NCName'。

【问题讨论】:

  • 架构说它是由 XmlGrid.net 生成的。从来没有听说过那个工具,但如果它生成这个模式,它显然是垃圾。 &lt;xs:attribute name="xmlns:ns2" 是可笑的错误。寻找更好的工具。
  • @MichaelKay:&lt;xs:element name="ns2:Response"&gt; 也好不到哪里去。而且,是的,XMLGrid.net 确实从 OP 的 XML 生成了这样的 XSD——我刚刚检查过;这不仅仅是一代后编辑不佳的情况。呃。
  • 您需要将第二个 XSD 导入主 XSD,以便在命名空间中有一个根元素,而在没有命名空间的子元素中。具体方法请参见my updated answer

标签: java xml xsd xsd-validation


【解决方案1】:

您的 XML 和 XSD 需要进行几处更改,包括:

  • &lt;xs:element name="ns2:Response"&gt; 更改为<xs:element name="Response">,因为元素名称声明必须是 非殖民化名称 (NCNAME)。
  • 删除&lt;xs:attribute name="xmlns:ns2".../> 因为命名空间 不能声明为属性。
  • targetNamespace 添加到与 XML 文档中根元素的命名空间匹配的 XSD。
  • 为那些您希望不在命名空间中的元素导入单独的 XSD(假设您的根元素在命名空间中)。您必须使用单独的 XSD 来完成此操作。

总而言之,您的 XML,

<?xml version="1.0" encoding="UTF-8"?>
<ns2:Response xmlns:ns2="http://test.com/"
              Id="122212">
  <Infos size="1">
    <Info>
      <name>test</name>
    </Info>
  </Infos>
</ns2:Response>

将针对这些 XSD 成功验证:

主要

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified"
           xmlns:ns="http://test.com/"
           targetNamespace="http://test.com/">
  <xs:import schemaLocation="Infos.xsd"/>
  <xs:element name="Response">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Infos"/>
      </xs:sequence>
      <xs:attribute name="Id" type="xs:int"></xs:attribute>
    </xs:complexType>
  </xs:element>
</xs:schema>

导入(Infos.xsd)

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Infos">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Info">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="name" type="xs:string"></xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
      <xs:attribute name="size" type="xs:int"></xs:attribute>
    </xs:complexType>
  </xs:element>
</xs:schema>

【讨论】:

    【解决方案2】:

    正如上面的答案所暗示的,我能够通过将目标名称空间添加到架构中并将 ns 前缀添加到所有元素来获取解析的文件。

    <?xml version="1.0" encoding="UTF-8"?>
    <ns2:Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://test.com testq1.xsd"     xmlns:ns2="http://test.com" Id="122212">
    <ns2:Infos size="1">
        <ns2:Info>
            <ns2:name>test</ns2:name>
        </ns2:Info>
    </ns2:Infos>
    

    和架构:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://test.com"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified"> 
    
    <xs:element name="Response">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="Infos">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="Info">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="name" type="xs:string"></xs:element>
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                        <xs:attribute name="size" type="xs:int"></xs:attribute>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
    
            <xs:attribute name="Id" type="xs:int"></xs:attribute>
        </xs:complexType>
    </xs:element>
    </xs:schema>
    

    【讨论】:

    • Hi ns 前缀并非适用于所有元素。是否只有响应元素。我该如何解决这个问题?
    • @user1921479:您需要将另一个 XSD 导入到主 XSD 中,以便在命名空间中有一个根元素,而在没有命名空间的子元素中。具体方法请参见my updated answer
    • 我的错...我假设由于您有 elementFormDefault="qualified" 并且架构中没有 targetNamespace,那是一个错误...所以在我的中我添加了假设所有元素都在 ns2 命名空间中
    【解决方案3】:

    您可以通过两种方式解决此问题。

    方法 1 - 多个架构

    更典型的方法是为每个使用的命名空间设置一个模式。 所以你最终会得到像这样的架构

    SampleXml0.xsd

    <?xml version="1.0" encoding="utf-8"?>
    <!-- Created with Liquid Studio 2017 (https://www.liquid-technologies.com) -->
    <xs:schema xmlns:ns2="http://test.com/" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://test.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:import schemaLocation="C:\Temp\StackOverflow\42351409\SampleXml1.xsd" />
      <xs:element name="Response">
        <xs:complexType>
          <xs:sequence>
            <xs:element minOccurs="0" ref="Infos" />
          </xs:sequence>
          <xs:attribute name="Id" type="xs:unsignedInt" use="optional" />
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    SampleXml1.xsd

    <?xml version="1.0" encoding="utf-8"?>
    <!-- Created with Liquid Studio 2017 (https://www.liquid-technologies.com) -->
    <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="Infos">
        <xs:complexType>
          <xs:sequence>
            <xs:element minOccurs="0" name="Info">
              <xs:complexType>
                <xs:sequence>
                  <xs:element minOccurs="0" name="name" type="xs:string" />
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:sequence>
          <xs:attribute name="size" type="xs:unsignedByte" use="optional" />
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    方法 2 - 更改 elementFormDefault

    现在这对您的示例来说是非常具体的,但由于它是唯一使用命名空间限定的根元素,因此可以将 elementFormDefault 更改为 unqualified。这具有强制在架构中定义为根元素的元素具有命名空间限定的效果,而其他元素则没有。

    <?xml version="1.0" encoding="utf-8" ?>
    <!--Created with Liquid Studio 2017 (https://www.liquid-technologies.com)-->
    <xs:schema xmlns:ns2="http://test.com/" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://test.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:element name="Response">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="Infos" minOccurs="0">
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name="Info" minOccurs="0">
                                    <xs:complexType>
                                        <xs:sequence>
                                            <xs:element name="name" type="xs:string" minOccurs="0" />
                                        </xs:sequence>
                                    </xs:complexType>
                                </xs:element>
                            </xs:sequence>
                            <xs:attribute name="size" type="xs:unsignedByte" use="optional" />
                        </xs:complexType>
                    </xs:element>
                </xs:sequence>
                <xs:attribute name="Id" type="xs:unsignedInt" use="optional" />
            </xs:complexType>
        </xs:element>
    </xs:schema>
    

    我可能会建议创建多个模式,因为 elementformdefault 通常会被客户端实现忽略并忽略。

    【讨论】:

      【解决方案4】:

      为什么是三个&lt;xs:sequence&gt; 元素?你真的需要那个吗?你能更好地解释你的代码是如何组织的吗?通常它很简单,像这样:

      <xsd:element name="ns2:Response">
              <xsd:complexType>
                  <xsd:sequence>
                      <xsd:element name="name" type="xs:string" />
                  </xsd:sequence>
              </xsd:complexType>
      </xsd:element>
      

      【讨论】:

      • 嵌套三个级别的xs:sequence 很好,与OP的问题无关。
      猜你喜欢
      • 1970-01-01
      • 2015-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-02
      相关资源
      最近更新 更多