0

我正在尝试验证一个大致如下所示的一堆 XML 文件(示例完整文件位于 Gist):

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!-- ... -->
  <ProjectExtensions>
    <Borland.Personality>Default.Personality</Borland.Personality>
    <Borland.ProjectType />
    <BorlandProject>
  <BorlandProject xmlns=""> <Default.Personality> </Default.Personality> </BorlandProject></BorlandProject>
  </ProjectExtensions>
  <!-- ... -->
</Project>

我知道嵌套<BorlandProject xmlns="">很奇怪,但是我们存储库中的很多 XML 文件都是这样的,我想验证它们是否正常。

这些文件使用 MSBuild 定义的子集。到目前为止,我已经尝试过这样的事情(再次:Gist 上的完整文件):

<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" version="1.0"
  targetNamespace="http://schemas.microsoft.com/developer/msbuild/2003"
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="Project" type="ProjectType"/>
  <!-- ... -->
  <xsd:complexType name="ProjectExtensionsType">
    <xsd:sequence>
      <xsd:element name="Borland.Personality" type="xsd:string"/>
      <xsd:element name="Borland.ProjectType" type="xsd:string"/>
      <xsd:element name="BorlandProject" type="BorlandProjectType"/>
    </xsd:sequence>
  </xsd:complexType>
  <xsd:complexType name="BorlandProjectType">
    <xsd:choice>
      <xsd:sequence>
        <xsd:element name="Default.Personality" type="xsd:string"/>
      </xsd:sequence>
      <xsd:element name="BorlandProject" type="BorlandProjectType"/>
    </xsd:choice>
  </xsd:complexType>
  <!-- ... -->
</xsd:schema>

使用如下错误消息验证 barfs:

Error: The element 'BorlandProject' in namespace 'http://schemas.microsoft.com/developer/msbuild/2003'  
has invalid child element 'BorlandProject'.  
List of possible elements expected:   
'Default.Personality, BorlandProject' in namespace 'http://schemas.microsoft.com/developer/msbuild/2003'.  
<BorlandProject>

我想这是因为奇怪的xmlns=""内心<BorlandProject xmlns="">

两个问题:

  1. 我的xmlns=""假设对吗?
  2. 如何验证此<BorlandProject xmlns="">元素?

编辑

感谢ColdFusion的回答。这就是我最终所做的,因为BorlandProject既可以是合格的,也可以是不合格的:

  <xsd:complexType name="BorlandProjectType">
    <xsd:choice>
      <xsd:sequence>
        <xsd:element name="Default.Personality" type="xsd:string"/>
      </xsd:sequence>
      <!-- Delphi <= 2010 can have a nested `BorlandProject` element, sometimes unqualified (with xmlns=""), sometimes qualified -->
      <xsd:choice>
        <xsd:element name="BorlandProject" form="unqualified" type="BorlandProjectTypeUnqualified"/>
        <xsd:element name="BorlandProject" type="BorlandProjectTypeQualified"/>
      </xsd:choice>
    </xsd:choice>
  </xsd:complexType>
  <xsd:complexType name="BorlandProjectTypeUnqualified">
    <xsd:sequence>
      <xsd:element name="Default.Personality" form="unqualified" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
  <xsd:complexType name="BorlandProjectTypeQualified">
    <xsd:sequence>
      <xsd:element name="Default.Personality" type="xsd:string"/>
    </xsd:sequence>
  </xsd:complexType>
4

2 回答 2

3

我的 xmlns="" 假设正确吗?

是的。拥有xmlns=""并没有错。"" 也是一个命名空间——全局命名空间(或“nonamespace”)。

如何验证此元素?

nonamespace 中的元素称为unqualified

只要您需要不合格的所有元素都是本地元素(嵌套在其他一些元素中),就可以使用form="unqualified"属性明确声明(对于每个特定元素)。

注意:是否所有本地元素(在架构中定义)都是合格的,elementFormDefault<xsd:schema>. 但是你可以混合它,使一些局部元素合格而一些不合格。

例如,您的 XML 文件(在您的问题中提供)可以针对此架构进行验证:

<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
  version="1.0"
  targetNamespace="http://schemas.microsoft.com/developer/msbuild/2003"
  xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">

  <xsd:element name="Project" type="ProjectType"/>

  <xsd:complexType name="ProjectType">
    <xsd:sequence>
      <xsd:element name="ProjectExtensions" type="ProjectExtensionsType"/>
    </xsd:sequence>
  </xsd:complexType>

  <!-- ... -->
  <xsd:complexType name="ProjectExtensionsType">
    <xsd:sequence>
      <xsd:element name="Borland.Personality" type="xsd:string"/>
      <xsd:element name="Borland.ProjectType" type="xsd:string"/>
      <xsd:element name="BorlandProject" type="BorlandProjectType"/>
    </xsd:sequence>
  </xsd:complexType>
  <xsd:complexType name="BorlandProjectType">
    <xsd:choice>
      <xsd:sequence>
        <xsd:element name="Default.Personality" type="xsd:string"
                     form="unqualified"/>
      </xsd:sequence>
      <xsd:element name="BorlandProject" type="BorlandProjectType"
                   form="unqualified"/>
    </xsd:choice>
  </xsd:complexType>
  <!-- ... -->
</xsd:schema>

请注意,根据该架构,您实际上有两个BorlandProject元素:一个在命名空间中http://schemas.microsoft.com/developer/msbuild/2003,另一个在没有命名空间中。我不知道,你是否真的需要这个......但这就是你的 XML 的编写方式。

于 2013-09-01T22:25:16.897 回答
1
  1. 是的,在删除 xmlns="" 之后,XML 会进行验证。

  2. a) 最简单的解决方案是从 XML 中删除无效的 xmlns。

    b) 更难的是拥有另一个您导入的模式,它没有定义另一个您可以引用的 BorlantProjectType 的命名空间。我试过这个,但无法让它工作。

    c) 另一种可能性是基于 XML 生成一个新模式,然后对其进行验证。我这样做了,然后对其进行了一些调整,以使包含中的嵌套发生。然而,由于这只是针对一个样本进行了测试,因此可能需要进行更多调整。XSD 在这里https://gist.github.com/anonymous/6408209 & https://gist.github.com/Dijkgraaf/6408223

编辑:d)选择ColdFusion给出的答案要简单得多。

于 2013-09-02T00:25:52.357 回答