You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使XSD的DataArray_t支持任意简单类型,解决大数值存储问题?

XML粒子数据存储XSD问题解决方案

问题描述

我们尝试用XML格式存储粒子数据,现有XSD代码基本可用,但向DataArray_t存储大unsigned long值时出现异常,原因是DataArrayList_t的基类型为xsd:decimal(无法精确表示超大无符号长整数)。由于DataArray_t需要支持存储任意类型数据(如int、unsigned long、double等),希望知道是否可通过参数形式任意修改DataArrayList_t的itemType?

现有XSD代码:

<?xml version="1.0"?>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

 <xsd:simpleType name='DataArrayList_t'>
    <xsd:list itemType='xsd:decimal'/>
  </xsd:simpleType>

  <xsd:complexType name="DataArray_t">
    <xsd:simpleContent>
      <xsd:extension base="DataArrayList_t"> <!-- hier typ der daten in liste  --> 
        <xsd:attribute name="type" use="required">
          <xsd:simpleType>
            <xsd:restriction base="xsd:string">
              <xsd:enumeration value="Int8"/>
              <xsd:enumeration value="UInt8"/>
              <xsd:enumeration value="Int16"/>
              <xsd:enumeration value="UInt16"/>
              <xsd:enumeration value="Int32"/>
              <xsd:enumeration value="UInt32"/>
              <xsd:enumeration value="Int64"/>
              <xsd:enumeration value="UInt64"/>
              <xsd:enumeration value="Float32"/>
              <xsd:enumeration value="Float64"/>
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:attribute>
        <xsd:attribute name="Name" type="xsd:string" use="required"/>
        <xsd:attribute name="NumberOfComponents" type="xsd:integer" use="required"/>
        <xsd:attribute name="format" type="xsd:string" fixed="ascii"/>
        <xsd:attribute name="offset" type="xsd:integer" use="optional"/>
      </xsd:extension>
    </xsd:simpleContent>
  </xsd:complexType>

  <xsd:complexType name="PieceUnstructuredGrid_t">
    <xsd:sequence>
      <xsd:element name="PointData">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="DataArray" type="DataArray_t" minOccurs="0" maxOccurs="unbounded"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="CellData">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="DataArray" type="DataArray_t" minOccurs="0" maxOccurs="unbounded"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="Points">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="DataArray" type="DataArray_t" minOccurs="0" maxOccurs="unbounded"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
      <xsd:element name="Cells">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="DataArray" type="DataArray_t" minOccurs="0" maxOccurs="unbounded"/>
          </xsd:sequence>
        </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
    <xsd:attribute name="NumberOfPoints" type="xsd:integer" use="required"/>
    <xsd:attribute name="NumberOfCells" type="xsd:integer" use="required"/>
  </xsd:complexType>    
</xsd:schema>

解决方案说明

XSD 1.0不支持通过参数动态修改list的itemType,因为类型定义是静态的,无法根据属性值动态调整。但可以通过以下几种方案解决类型兼容问题:

方案1:改用字符串列表存储(最灵活)

将DataArrayList_t的基类型改为xsd:string,所有数值以字符串形式存储,通过type属性约定实际类型,在解析阶段再做类型转换。这种方式完全避免了数值类型的精度限制,能支持所有枚举的类型。

修改后的DataArrayList_t定义:

<xsd:simpleType name='DataArrayList_t'>
  <xsd:list itemType='xsd:string'/>
</xsd:simpleType>

方案2:为每种类型定义单独列表(XSD 1.0严格校验)

为每个枚举类型定义对应的list类型,然后在DataArray_t中使用<xsd:choice>选择对应类型的列表,同时在应用层保证type属性与实际列表类型一致。

示例修改片段:

<!-- 定义各类型对应的列表 -->
<xsd:simpleType name='Int8List_t'>
  <xsd:list itemType='xsd:byte'/>
</xsd:simpleType>
<xsd:simpleType name='UInt8List_t'>
  <xsd:list itemType='xsd:unsignedByte'/>
</xsd:simpleType>
<xsd:simpleType name='UInt64List_t'>
  <xsd:list itemType='xsd:unsignedLong'/>
</xsd:simpleType>
<!-- 其他类型列表定义省略 -->

<!-- 修改DataArray_t结构 -->
<xsd:complexType name="DataArray_t">
  <xsd:choice>
    <xsd:element name="Int8Data" type="Int8List_t"/>
    <xsd:element name="UInt8Data" type="UInt8List_t"/>
    <xsd:element name="UInt64Data" type="UInt64List_t"/>
    <!-- 其他类型对应的element添加 -->
  </xsd:choice>
  <xsd:attribute name="type" use="required">
    <!-- 原有枚举定义不变 -->
  </xsd:attribute>
  <!-- 其他属性定义不变 -->
</xsd:complexType>

该方案能在XSD层面实现严格类型校验,但定义较为冗长,新增类型时需同步扩展XSD。

方案3:使用XSD 1.1条件类型赋值(最优雅)

如果可以升级到XSD 1.1,可利用条件类型赋值特性,根据type属性的值动态绑定对应的列表类型,完美匹配需求。

示例实现片段:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
            vc:minVersion="1.1">

  <!-- 定义各类型对应的列表 -->
  <xsd:simpleType name='Int8List_t'>
    <xsd:list itemType='xsd:byte'/>
  </xsd:simpleType>
  <xsd:simpleType name='UInt8List_t'>
    <xsd:list itemType='xsd:unsignedByte'/>
  </xsd:simpleType>
  <xsd:simpleType name='UInt64List_t'>
    <xsd:list itemType='xsd:unsignedLong'/>
  </xsd:simpleType>
  <!-- 其他类型列表定义省略 -->

  <!-- 带条件类型赋值的DataArray_t -->
  <xsd:complexType name="DataArray_t">
    <xsd:simpleContent>
      <xsd:extension base="xsd:anySimpleType">
        <xsd:attribute name="type" use="required">
          <!-- 原有枚举定义不变 -->
        </xsd:attribute>
        <!-- 其他属性定义不变 -->
      </xsd:extension>
    </xsd:simpleContent>
    <!-- 根据type属性选择对应列表类型 -->
    <xsd:alternative test="@type='Int8'" type="Int8List_t"/>
    <xsd:alternative test="@type='UInt8'" type="UInt8List_t"/>
    <xsd:alternative test="@type='UInt64'" type="UInt64List_t"/>
    <!-- 其他类型的alternative添加 -->
    <xsd:alternative type="xsd:string"/> <!-- 默认 fallback -->
  </xsd:complexType>

  <!-- 原有PieceUnstructuredGrid_t等定义不变 -->
</xsd:schema>

该方案既保留了type属性的语义,又能在XSD层面完成类型校验,但需要支持XSD 1.1的解析器(如Xerces2、Saxon)。

内容的提问来源于stack exchange,提问作者Felix Hoppe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 01:05:26