【问题标题】:XML xs:choice SQLXMLBulkloadXML xs:选择 SQLXMLBulkload
【发布时间】:2026-01-25 05:35:01
【问题描述】:

我有一些 XML 文件需要批处理到 SQL Server 中。以下 Schema 和 XML 部分概述了我遇到问题的一个领域。

<xs:complexType>
    <xs:sequence>
        <xs:choice maxOccurs="unbounded">
            <xs:element name="TextLine" type="xs:string" sql:field="AdvertLine" sql:relation="XmlAdvert" sql:relationship="XmlAdvert" />
            <xs:element name="BreakPoint" sql:is-constant="1" />
        </xs:choice>
    </xs:sequence>
</xs:complexType>

<Advert>
 <AdvertText>
  <TextLine>Isuzu 4 X 4TRUCKMAN</TextLine> 
  <BreakPoint /> 
  <TextLine>2.0TD, Red, 5 dr, 60,000 miles, MOT, 5 SEATER</TextLine> 
  <BreakPoint /> 
  <TextLine>£2500</TextLine>
  <BreakPoint /> 
  <TextLine>01234 567890</TextLine> 
 </AdvertText>
</Advert>

但由于 SQLXMLBulkload 不支持 xs:choice,我想知道是否有另一种表示方式,因为没有 xs:choice 部分,xs:sequence 在到达第二个 TextLine 时立即无效。

【问题讨论】:

    标签: sqlxml


    【解决方案1】:

    我不熟悉 SQLXMLBulkload,但这是我的想法:

    我不确定相邻的 TextLineBreakPoint 元素之间是否存在任何关系。假设没有,那么最简单的解决方案可能是使用 XSLT 来转换架构和数据以消除对 choice 的需要。

    请注意,我在两个元素上都插入了maxOccurs="unbounded"。如果这不起作用,那么还有一种替代方法应该起作用;见下文。

    <xs:complexType>
        <xs:sequence>
            <xs:element name="TextLine" type="xs:string" sql:field="AdvertLine" sql:relation="XmlAdvert" sql:relationship="XmlAdvert" maxOccurs="unbounded"/>
            <xs:element name="BreakPoint" sql:is-constant="1" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    

    等效的 XML 是:

    <Advert>
     <AdvertText>
      <TextLine>Isuzu 4 X 4TRUCKMAN</TextLine> 
      <TextLine>2.0TD, Red, 5 dr, 60,000 miles, MOT, 5 SEATER</TextLine> 
      <TextLine>£2500</TextLine>
      <TextLine>01234 567890</TextLine> 
      <BreakPoint /> 
      <BreakPoint /> 
      <BreakPoint /> 
     </AdvertText>
    </Advert>
    

    但据我所知,SQLXMLBulkload 也不喜欢这种安排。在那种情况下,仅基于您的示例 XML,我敢打赌它会接受这个:

    匹配的 XML 是:

    <Advert>
     <AdvertText>
        <TextLines>
          <TextLine>Isuzu 4 X 4TRUCKMAN</TextLine> 
          <TextLine>2.0TD, Red, 5 dr, 60,000 miles, MOT, 5 SEATER</TextLine> 
          <TextLine>£2500</TextLine>
          <TextLine>01234 567890</TextLine>
        </TextLines> 
      <BreakPoints> 
          <BreakPoint /> 
          <BreakPoint /> 
          <BreakPoint /> 
      </BreakPoints> 
     </AdvertText>
    </Advert>
    

    这仍然没有解决如何编写您需要的 XSLT 的问题,但也许这是一个开始。

    【讨论】:

    • 我认为你可能是对的。我不喜欢 XML 的结构,但除了在将其发送到 SQLXMLBulkload 之前进行一些预处理之外,我无能为力。我需要做的就是去掉空的 BreakPoint 元素,这一切都很好。