SQL从查询创建XML而不重复标记

时间:2017-03-31 15:46:14

标签: sql sql-server xml sql-server-2012

我试着编写一个生成xml和im的sql查询,但我需要能够阻止它重复标记。

这是我目前使用的查询

select DISTINCT
  objecttype.Type 
, object.text
, objectelement.Value
, objectlanguage.CultureInfo
, isnull(objectelementtext.ElementText, objectelement.Value)
from [object] object
    inner join [objecttype] objecttype
        on object.ObjectTypeID = objecttype.ObjectTypeID
    inner join [ObjectElement] objectelement
        on object.ObjectID = objectelement.ObjectID
    outer APPLY 
        (
            select objectlanguage.ObjectLanguageID,    objectlanguage.CultureInfo
                from [ObjectLanguage] objectlanguage
                where active = 1
        ) objectlanguage
    left join [ObjectElementText] objectelementtext
        on objectelementtext.ObjectElementID = objectelement.ObjectElementID
            and objectlanguage.ObjectLanguageID = objectelementtext.ObjectLanguageID
FOR XML AUTO, ELEMENTS, ROOT('Translations')

因此,这会生成XML,但看起来如下所示。

    <Translations>
      <objecttype>
        <Type>Report</Type>
        <object>
  <text>TrayList</text>
  <objectelement>
    <Value>***** For Information Only *****</Value>
    <objectlanguage>
      <CultureInfo>en-gb</CultureInfo>***** For Information Only *****</objectlanguage>
    <objectlanguage>
      <CultureInfo>en-tt</CultureInfo>******** For Information Only *****</objectlanguage>
    <objectlanguage>
      <CultureInfo>en-us</CultureInfo>***** For Information Only *****</objectlanguage>
    <objectlanguage>
      <CultureInfo>it-it</CultureInfo>***** Solo Per Informazione *****</objectlanguage>
    <objectlanguage>
      <CultureInfo>zh-cn</CultureInfo>***** For Information Only *****</objectlanguage>
  </objectelement>

我想要做的是阻止它重复开始标记,例如

    <objectlanguage>
        <CultureInfo ci="en-gb" text ="***** For Information Only*****"/>
        <CultureInfo ci="en-it" text ="***** For Information Only*****"/>
        <CultureInfo ci="en-us" text ="***** For Information Only*****"/>
        <CultureInfo ci="zn-cn" text ="***** For Information Only*****"/>
        <CultureInfo ci="it-tt" text ="***** For Information Only*****"/>
    </objectlanguage>

任何对此的帮助将非常感谢请,我想我是在正确的行,但我需要调整我的查询一些如何告诉它不重复它们但我不确定如何。

2 个答案:

答案 0 :(得分:3)

您的预期输出不是有效的XML。没有<SomeElement="content"/> ...

看看这个例子:

DECLARE @dummy TABLE(CultureInfo VARCHAR(100),SomeText VARCHAR(100));
INSERT INTO @dummy VALUES ('en-gb','Today is Friday')
                         ,('de-de','Heute ist Freitag');
SELECT CultureInfo AS [@ci]
      ,SomeText AS [@text] 
FROM @dummy
FOR XML PATH('CultureInfo'),ROOT('objectlanguage');

结果

<objectlanguage>
  <CultureInfo ci="en-gb" text="Today is Friday" />
  <CultureInfo ci="de-de" text="Heute ist Freitag" />
</objectlanguage>

您应该更喜欢FOR XML PATH因为它对最终结构影响最大。使用FOR XML AUTO,您可以让其他人为您决定...并使用ELEMENTS强制引擎将您的内容放入元素而不是属性......

更新

这是一次盲目飞行,但你可能会尝试这样的事情

  select DISTINCT
  objecttype.Type 
, object.text
, (
    SELECT CultureInfo AS [@ci]
          ,SomeText AS [@text] 
    FROM ObjectLanguage
    WHERE active=1 AND ObjectLanguage.ObjectLanguageID=ObjectElement.ObjectLanguageID
    FOR XML PATH('CultureInfo'),ROOT('objectlanguage'),TYPE
  )
  --, more columns
  FROM ... the rest without objectLanguage

答案 1 :(得分:0)

只是为了给每个人一个更新,我已经使用xml explicit完成了脚本,它运行得很好。

我使用的脚本,如果它可以帮助其他任何人如下

select 
DISTINCT
  1 AS TAG
, NULL AS PARENT, 
  objecttype.Type as [ObjectType!1!Text]
, NULL as [Object!2!Text]                                                           
, NULL as [ObjectElement!3!ObjectRef]                                                       
, NULL as [ObjectElement!3!Text]                                                
, NULL as [ObjectElementText!4!Culture]                                             
, NULL as [ObjectElementText!4!Text]        
from [object] object
    inner join [objecttype] objecttype
        on object.ObjectTypeID = objecttype.ObjectTypeID

UNION ALL

select
DISTINCT 
  2 AS TAG
, 1 AS PARENT, 
  objecttype.Type                                                           
, object.text
, NULL                                                      
, NULL                                          
, NULL                                          
, NULL                                                              
from [object] object
    inner join [objecttype] objecttype
        on object.ObjectTypeID = objecttype.ObjectTypeID

UNION ALL


select 
DISTINCT
  3 AS TAG
, 2 AS PARENT, 
  objecttype.Type as ObjectType                                                     
, object.text as [Object]                                                           
, objectelement.ObjectRef as [ObjectRef]
, objectelement.Value as [ObjectElement]                                                
, NULL
, NULL
from [object] object
    inner join [objecttype] objecttype
        on object.ObjectTypeID = objecttype.ObjectTypeID
    inner join [ObjectElement] objectelement
        on object.ObjectID = objectelement.ObjectID

UNION ALL

SELECT
DISTINCT 
  4 AS TAG
, 3 AS PARENT, 
  objecttype.Type as ObjectType                                                         
, object.text as [Object]   
, objectelement.ObjectRef as [ObjectRef]                                                        
, objectelement.Value as [ObjectElement]                                                
, objectlanguage.CultureInfo as [Culture]                                               
, isnull(objectelementtext.ElementText, objectelement.Value) as [ObjectElementText]     
from [object] object
    inner join [objecttype] objecttype
        on object.ObjectTypeID = objecttype.ObjectTypeID
    inner join [ObjectElement] objectelement
        on object.ObjectID = objectelement.ObjectID
    outer APPLY 
        (
            select objectlanguage.ObjectLanguageID, objectlanguage.CultureInfo
                from [ObjectLanguage] objectlanguage
                where active = 1
        ) objectlanguage
    left join [ObjectElementText] objectelementtext
        on objectelementtext.ObjectElementID = objectelement.ObjectElementID
            and objectlanguage.ObjectLanguageID = objectelementtext.ObjectLanguageID
ORDER BY 
  [ObjectType!1!Text]
, [Object!2!Text]
, [ObjectElement!3!ObjectRef]
, [ObjectElement!3!Text]
, [ObjectElementText!4!Culture]
, [ObjectElementText!4!Text]
FOR XML EXPLICIT, ROOT('Translations')