将XML中的属性批量加载到单个表格中的SQLXML

7

简言之;

我正在尝试使用SQLXML Bulk Loader (4.0)来加载类似于以下样式的XML数据;

<?xml version = "1.0" encoding = "UTF-8"?>
<CarSales>
 <Client>
  <ID >3</ID>
  <ClientName>John Smith3</ClientName>
  <Country name="Colombia"/>
 </Client>
 <Client>
  <ID>7</ID>
  <ClientName>Slow Sid</ClientName>
  <Country name="Bolivia"/>
 </Client>
 <Client>
  <ID>10</ID>
  <ClientName>Missing Town</ClientName>
  <Country name="Argentina"/>
 </Client>
</CarSales>

我希望能够在我正在使用的唯一表格(“Client_XMLBulkLoad”,该表格还包含客户名称和ID)的一列中捕获国家名称属性。这是否可能?
更多细节
这是我目前在相应XSD中拥有的内容(其中“Country”被注释掉)。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sql = "urn:schemas-microsoft-com:mapping-schema">
 <xsd:element name = "CarSales" sql:is-constant = "1" >
  <xsd:complexType>
   <xsd:sequence>
    <xsd:element name = "Client" sql:relation="Client_XMLBulkLoad"
          maxOccurs = "unbounded">
      <xsd:complexType>
       <xsd:sequence>
        <xsd:element name = "ID" type = "xsd:integer" 
                     sql:field = "ID" />
        <xsd:element name = "ClientName" type = "xsd:string"
                     sql:field = "ClientName" />
        <!-- <xsd:element name="Country" minOccurs="0" maxOccurs="unbounded">
                <xsd:complexType>
                  <xsd:attribute name="name" type="xsd:string" sql:field = "Country" />
                </xsd:complexType> 
        </xsd:element> -->
       </xsd:sequence>
      </xsd:complexType>
     </xsd:element>
    </xsd:sequence>
   </xsd:complexType>
  </xsd:element>
</xsd:schema>

如果我尝试使用“Country”不变进行批量加载,则会收到错误消息,指出需要在“Country”上设置模式关系。然而,根据我所阅读的所有内容,关系是在不同表之间设置的,而不是为了导入与所有其他数据相同表上的属性。

或者,我已经尝试使用“is-constant =“1””标记标记“Country”元素,但结果会出现错误,指出“常量/固定元素不能具有属性”。

那么,当国家名称属于与客户名称和ID相同的表时,我该如何捕获它?


以下是我正在使用的实际架构(它是一个嵌套架构)

架构根:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="NewDataSet" targetNamespace="http://scap.nist.gov/schema/feed/vulnerability/2.0" xmlns:mstns="http://scap.nist.gov/schema/feed/vulnerability/2.0" xmlns="http://scap.nist.gov/schema/feed/vulnerability/2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:app1="http://scap.nist.gov/schema/vulnerability/0.4" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
  <xs:import namespace="http://scap.nist.gov/schema/vulnerability/0.4" schemaLocation="DELTE_app1.xsd" />
  <xs:element name="nvd" sql:is-constant = "1">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="entry" minOccurs="0" maxOccurs="unbounded" sql:relation="NVD.CVE">
          <xs:complexType>
            <xs:sequence>
              <xs:element ref="app1:cwe" minOccurs="0"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

架构子元素:

<?xml version="1.0" standalone="yes"?>
<xs:schema targetNamespace="http://scap.nist.gov/schema/vulnerability/0.4" xmlns:mstns="http://scap.nist.gov/schema/feed/vulnerability/2.0" xmlns="http://scap.nist.gov/schema/vulnerability/0.4" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:app2="http://cpe.mitre.org/language/2.0" xmlns:app3="http://scap.nist.gov/schema/cvss-v2/0.2" xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
  <xs:element name="cwe" msdata:Prefix="vuln" sql:field="CWE">
    <xs:complexType>
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="id" form="unqualified" type="xs:string" sql:field="CWE"/>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>
  </xs:element>
</xs:schema>

我正在加载的XML文件:

<?xml version='1.0' encoding='UTF-8'?>
<nvd xmlns:scap-core="http://scap.nist.gov/schema/scap-core/0.1" xmlns:cvss="http://scap.nist.gov/schema/cvss-v2/0.2" xmlns:vuln="http://scap.nist.gov/schema/vulnerability/0.4" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:patch="http://scap.nist.gov/schema/patch/0.1" xmlns="http://scap.nist.gov/schema/feed/vulnerability/2.0" xmlns:cpe-lang="http://cpe.mitre.org/language/2.0" nvd_xml_version="2.0" pub_date="2015-07-10T03:00:00" xsi:schemaLocation="http://scap.nist.gov/schema/patch/0.1 http://nvd.nist.gov/schema/patch_0.1.xsd http://scap.nist.gov/schema/feed/vulnerability/2.0 http://nvd.nist.gov/schema/nvd-cve-feed_2.0.xsd http://scap.nist.gov/schema/scap-core/0.1 http://nvd.nist.gov/schema/scap-core_0.1.xsd">
<entry id="CVE-2015-0016">
    <vuln:cwe id="CWE-22"/>
  </entry>
</nvd>

请注意:这个方法是行得通的,但我需要在元素级别和属性级别都加上 [sql:field="CWE"]。如果我不加这个额外的 "sql:field",就会出现一个错误,说“列 'cwe' 在架构中被定义了,但在数据库中不存在”。如果我在该元素上添加一个“是常量”的标记,那么我就会得到“常量元素不能包含属性”的错误。所以我找到的唯一解决方案就是让它重复分配 sql:field="CWE"。

1个回答

4
您需要通过处理SQL字段来创建一个具有简单内容的复杂类型定义。
请参考<xsd:simpleContent>元素<xsd:extension>元素(复杂内容)
我还没有测试过,但以下模式应该可以工作。
更新: 我刚刚测试了一下,它的效果符合预期。
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sql="urn:schemas-microsoft-com:mapping-schema">
  <xsd:element name="CarSales" sql:is-constant="1">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="Client" sql:relation="Client_XMLBulkLoad" maxOccurs="unbounded">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="ID" type="xsd:integer" sql:field="ID"/>
              <xsd:element name="ClientName" type="xsd:string" sql:field="ClientName"/>
              <xsd:element name="Country" minOccurs="0" maxOccurs="unbounded">
                <xsd:complexType>
                  <xsd:simpleContent>
                    <xsd:extension base="xsd:string">
                      <xsd:attribute name="name" type="xsd:string" sql:field="Country"/>
                    </xsd:extension>
                  </xsd:simpleContent>
                </xsd:complexType>
              </xsd:element>
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

这个方法虽然有效,但我有一个后续问题。问题中的XML是我正在处理的简化示例。在我的实际情况中,“Country”元素实际上映射到不同的列名(该列名为“Citizenship”)。我将“sql:field =“Citizenship””添加到属性中,但我收到了一个错误消息,说“Country”不是已知的列。因此,我在模式中的属性之外还向“Country”元素添加了“sql:field =“Citizenship””。我做得对吗?看起来之后它似乎有效,但现在属性和元素都有“sql:field =“Citizenship””。 - n00b
@n00b 我需要查看 XML 和 Schema 文件。 - Kul-Tigin
请查看我的更新问题,其中包括相关的XML。请注意,尽管我只关心属性,但我不得不在所涉及的元素和属性中都添加“sql:field =”CWE“”。是否有方法可以解决这个问题,或者您能告诉我发生了什么? - n00b
1
@n00b 哦,现在我明白了。除非元素名称不等于 SQL 字段的名称,否则必须将 SQL 字段与元素(如果有属性,则也要映射)进行映射。这个例子没有使用 sql:field 也能工作,因为 XSD 元素和 SQL 字段共享相同的名称。是我的懒惰让你感到困惑了。抱歉,我应该说明一下的。 - Kul-Tigin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接