【问题标题】:Adding XML Schema Reference in SQL在 SQL 中添加 XML 模式引用
【发布时间】:2017-01-10 21:04:58
【问题描述】:

如果可以在我的 XML 根目录中添加对架构的直接引用,我终生都找不到。

这是我的代码:

Declare @Employee table (EmployeeID int,First_Name varchar(50),Last_Name varchar(50))
    Insert into @Employee values
    (1,'John','Smith'),
    (2,'Jane','Doe'  )


    Select (Select CreatedBy='My Organization',CreateDate=GetDate() For XML Path('RecordHeader'),Type ) 
          ,(Select * From @Employee For XML Path('Employee'),Type ) 
    For XML Path ('Employees'),Type

这会产生以下结果:

<Employees>
  <RecordHeader>
    <CreatedBy>My Organization</CreatedBy>
    <CreateDate>2016-10-18T16:09:48.110</CreateDate>
  </RecordHeader>
  <Employee>
    <EmployeeID>1</EmployeeID>
    <First_Name>John</First_Name>
    <Last_Name>Smith</Last_Name>
  </Employee>
  <Employee>
    <EmployeeID>2</EmployeeID>
    <First_Name>Jane</First_Name>
    <Last_Name>Doe</Last_Name>
  </Employee>
</Employees>

有没有办法在我的 SQL 中添加部分以使根标记包含以下内容:

<Employees xmlns="https://www.blahblah.org/blahblah/BlahSchema.xsd">

感谢您的帮助!

【问题讨论】:

    标签: sql sql-server xml tsql


    【解决方案1】:

    xmlns 总是有问题,所以我用了一点 hack

    Declare @Employee table (EmployeeID int,First_Name varchar(50),Last_Name varchar(50))
    Insert into @Employee values
    (1,'John','Smith'),
    (2,'Jane','Doe'  )
    
    Declare @XML xml = (
    Select (Select CreatedBy='My Organization',CreateDate=GetDate() For XML Path('RecordHeader'),Type ) 
          ,(Select * From @Employee For XML Path('Employee'),Type ) 
    For XML Path ('Employees'),Type
    )
    
    set @XML.modify('insert ( attribute MyNameSpace {"https://www.blahblah.org/blahblah/BlahSchema.xsd"}) into (/Employees)[1]')
    set @XML = replace(cast(@XML as nvarchar(max)),'[MyNameSpace]','xmlns')
    
    Select @XML
    

    返回

    <Employees xmlns="https://www.blahblah.org/blahblah/BlahSchema.xsd">
      <RecordHeader>
        <CreatedBy>My Organization</CreatedBy>
        <CreateDate>2017-01-10T15:19:42.873</CreateDate>
      </RecordHeader>
      <Employee>
        <EmployeeID>1</EmployeeID>
        <First_Name>John</First_Name>
        <Last_Name>Smith</Last_Name>
      </Employee>
      <Employee>
        <EmployeeID>2</EmployeeID>
        <First_Name>Jane</First_Name>
        <Last_Name>Doe</Last_Name>
      </Employee>
    </Employees>
    

    编辑以排除空值

    NULL 默认会被忽略,所以如果你想排除空值(非空),你可以通过 NullIf() 将值转换为 NULL。例如

    Declare @Employee table (EmployeeID int,First_Name varchar(50),Last_Name varchar(50))
    Insert into @Employee values
    (1,'John','Smith'),
    (2,'Jane','Doe'  ),
    (3,'Betty',null  ),  -- No element for Last_Name
    (4,'Susan',''  )     -- No element for Last_Name
    
    Declare @XML xml = (
    Select (Select CreatedBy='My Organization',CreateDate=GetDate() For XML Path('RecordHeader'),Type ) 
          ,(Select EmployeeID = NullIf(EmployeeID,'') 
                  ,First_Name = NullIf(First_Name,'')
                  ,Last_Name  = NullIf(Last_Name,'')
             From  @Employee For XML Path('Employee'),Type ) 
    For XML Path ('Employees'),Type
    )
    
    set @XML.modify('insert ( attribute MyNameSpace {"https://www.blahblah.org/blahblah/BlahSchema.xsd"}) into (/Employees)[1]')
    set @XML = replace(cast(@XML as nvarchar(max)),'[MyNameSpace]','xmlns')
    
    Select @XML
    

    【讨论】:

    • 谢谢约翰!你照常过来!
    • @ssokol91 很高兴它有帮助
    • 我也不知道直接的方法...从我这边+1。一个小提示:最好转换为 NVARCHAR(MAX),因为 XML 在内部是 16 位编码的,而且 - 除了性能 - VARCHAR 可能会弄乱一些特殊字符......还有一个想法:使用 STUFF 替换可能更容易以&lt;Employees xmlsn="blah"&gt; 开头的&lt;Employees&gt; 在字符串基...
    • @JohnCappelletti,我不知道,这看起来很傻......我的假设是,如果有人调用FROM OPENXML(或从你的 超重量级-伟大的功能)。更改 default 命名空间可能会产生巨大且不可预测的影响...
    • @ssokol91 查看更新/编辑。默认情况下会省略 Null,因此您可以通过 NullIf() 将空值设为空
    【解决方案2】:

    您可以使用WITH NAMESPACES 关键字,但这会将名称空间添加到所有节点:

    Declare @Employee table (EmployeeID int,First_Name varchar(50),Last_Name varchar(50))
    Insert into @Employee values
    (1,'John','Smith'),
    (2,'Jane','Doe'  );
    
    
    WITH XMLNAMESPACES (DEFAULT 'https://www.blahblah.org/blahblah/BlahSchema.xsd')
    Select (Select CreatedBy='My Organization',CreateDate=GetDate() For XML Path('RecordHeader'),Type ) 
          ,(Select * From @Employee For XML Path('Employee'),Type ) 
    For XML Path ('Employees'),Type
    

    结果:

    <Employees xmlns="https://www.blahblah.org/blahblah/BlahSchema.xsd">
      <RecordHeader xmlns="https://www.blahblah.org/blahblah/BlahSchema.xsd">
        <CreatedBy>My Organization</CreatedBy>
        <CreateDate>2017-01-10T16:36:23.450</CreateDate>
      </RecordHeader>
      <Employee xmlns="https://www.blahblah.org/blahblah/BlahSchema.xsd">
        <EmployeeID>1</EmployeeID>
        <First_Name>John</First_Name>
        <Last_Name>Smith</Last_Name>
      </Employee>
      <Employee xmlns="https://www.blahblah.org/blahblah/BlahSchema.xsd">
        <EmployeeID>2</EmployeeID>
        <First_Name>Jane</First_Name>
        <Last_Name>Doe</Last_Name>
      </Employee>
    </Employees>
    

    【讨论】:

    • 这看起来很有希望,但看起来它将它添加到每个父标签而不是根标签。谢了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    • 1970-01-01
    • 2011-11-07
    • 1970-01-01
    相关资源
    最近更新 更多