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

如何通过XSD将XML中geo元素按cat属性映射重命名并导入Excel?

问题:将含多geo元素的XML导入Excel生成扁平列表

原始XML数据

<divesites>
<site uuid='fb5d20c9' name='Name X' gps='40.123456 10.123456' description='type 1'>
  <geo cat='2' origin='0' value='Netherlands'/>
  <geo cat='3' origin='0' value='Zeeland'/>
  <geo cat='5' origin='0' value='foo'/>
</site>
<site uuid='febb4a6b' name='Name Y' gps='40.123456 10.123456' description='type 2'>
  <notes>some crazy note this is... </notes>
  <geo cat='2' origin='0' value='Spain'/>
  <geo cat='3' origin='0' value='Mallorca'/>
</site>
</divesites>

当前使用的XSD(问题:单site生成多行)

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="divesites" type="divesitesType"/>
  <xs:complexType name="geoType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:byte" name="cat" use="optional"/>
        <xs:attribute type="xs:byte" name="origin" use="optional"/>
        <xs:attribute type="xs:string" name="value" use="optional"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  <xs:complexType name="siteType">
    <xs:sequence>
      <xs:element type="xs:string" name="notes" minOccurs="0"/>
      <xs:element type="geoType" name="geo" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute type="xs:string" name="uuid" use="optional"/>
    <xs:attribute type="xs:string" name="name" use="optional"/>
    <xs:attribute type="xs:string" name="gps" use="optional"/>
    <xs:attribute type="xs:string" name="description" use="optional"/>
  </xs:complexType>
  <xs:complexType name="divesitesType">
    <xs:sequence>
      <xs:element type="siteType" name="site" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

需求

将不同cat属性的<geo>元素映射为独立字段:

  • <geo cat='2'> → Country
  • <geo cat='4'> → Town
    最终生成包含uuid、name、gps、description、notes、country、town等字段的扁平列表,每个<site>对应一行。

Excel的XML Schema限制

Excel不支持以下XML Schema元素结构,无法导入:

  • <any>:允许包含未在Schema中声明的元素
  • <anyAttribute>:允许包含未在Schema中声明的属性
  • 递归结构:如员工-经理层级嵌套,仅支持最多一层递归
  • 抽象元素:仅在Schema中声明,实际不使用,依赖其他元素替换
  • 替换组:允许用其他元素替换指定元素,通过<substitutionGroup>属性标记成员
  • 混合内容:在复杂类型定义中使用mixed="true"声明的内容,Excel不支持此类复杂类型的简单内容,但支持其中的子标签和属性

解决方案

方法1:使用XSLT转换XML为扁平结构(推荐)

通过XSLT将原始XML转换为每个<site>对应一行的扁平结构,再导入Excel,完全规避XSD的限制。

XSLT转换代码

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/divesites">
    <rows>
      <xsl:for-each select="site">
        <row>
          <uuid><xsl:value-of select="@uuid"/></uuid>
          <name><xsl:value-of select="@name"/></name>
          <gps><xsl:value-of select="@gps"/></gps>
          <description><xsl:value-of select="@description"/></description>
          <notes><xsl:value-of select="notes"/></notes>
          <country><xsl:value-of select="geo[@cat='2']/@value"/></country>
          <town><xsl:value-of select="geo[@cat='4']/@value"/></town>
          <!-- 可添加更多cat对应的字段,格式同上 -->
        </row>
      </xsl:for-each>
    </rows>
  </xsl:template>
</xsl:stylesheet>

使用步骤

  1. 将上述代码保存为transform.xsl
  2. 使用XML/XSLT转换工具(如在线转换器、本地XML编辑器)将原始XML转换为扁平XML
  3. 导入转换后的XML到Excel,即可得到每个<site>一行的扁平列表

方法2:调整XSD适配Excel映射(需修改原始XML)

若必须使用XSD,需重新定义<site>的结构,将不同cat的<geo>映射为独立可选元素,但要求原始XML的元素名与XSD定义一致(如<geo cat='2'>改为<country cat='2'>)。

修改后的XSD

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="divesites" type="divesitesType"/>
  
  <xs:complexType name="geoType">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute type="xs:byte" name="origin" use="optional"/>
        <xs:attribute type="xs:string" name="value" use="optional"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>
  
  <xs:complexType name="siteType">
    <xs:sequence>
      <xs:element type="xs:string" name="notes" minOccurs="0"/>
      <xs:element name="country" type="geoType" minOccurs="0">
        <xs:attribute name="cat" type="xs:byte" fixed="2"/>
      </xs:element>
      <xs:element name="town" type="geoType" minOccurs="0">
        <xs:attribute name="cat" type="xs:byte" fixed="4"/>
      </xs:element>
      <!-- 添加其他需要的geo类别元素 -->
      <xs:element type="geoType" name="geo" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
    <xs:attribute type="xs:string" name="uuid" use="optional"/>
    <xs:attribute type="xs:string" name="name" use="optional"/>
    <xs:attribute type="xs:string" name="gps" use="optional"/>
    <xs:attribute type="xs:string" name="description" use="optional"/>
  </xs:complexType>
  
  <xs:complexType name="divesitesType">
    <xs:sequence>
      <xs:element type="siteType" name="site" maxOccurs="unbounded" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 08:30:08