tags:

views:

257

answers:

1

I have some XML files that I need to batch process into SQL Server. The following Schema and XML sections outline an area I'm having trouble with.

<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>

But since xs:choice isn't supported in SQLXMLBulkload I wondered if there was another way of representing this as without the xs:choice section the xs:sequence is invalid as soon as it hits the second TextLine.

A: 

I'm not familiar with SQLXMLBulkload, but here are my thoughts:

I'm not sure if there's any relationship between adjacent TextLine and BreakPoint elements. Assuming that there isn't, then the simplest solution may be to use XSLT to transform the schema and data to eliminate the need for the choice.

Note that I've inserted maxOccurs="unbounded" on both elements. If that doesn't work, there's an alternate approach that should work; see below.

<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>

The equivalent XML would be:

<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>

But for all I know, SQLXMLBulkload won't like that arrangement either. In that case, based only on your example XML, I would bet that it would accept this:

with the matching XML being:

<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>

That still leaves open the question of how to write the XSLT that you'd need, but perhaps it's a start.

Dan Breslau
I think you might be right. I don't like the structure of the XML but there isn't much I can do about that other than a bit of pre-processing before I send it into SQLXMLBulkload. All i need to do is strip out the empty BreakPoint elements and it all works beautifully.