【问题标题】:Order attribute names in xml using t-sql使用 t-sql 在 xml 中排序属性名称
【发布时间】:2017-05-20 23:39:53
【问题描述】:

我需要按字母顺序对属性名称进行排序,并且我创建了以下代码,但它保留了 xml:

DECLARE @xml XML = N'<tt>
       <cpost s="a" cena="0.0000" cpost_id="16385" flprt="1" moq="0"
    valuta_id="2" nmatr_id="14117" norg_id="1791" />

       </tt>'

    SELECT
        t.query('.')
    FROM @xml.nodes('*/*') AS t(t)
    ORDER BY t.value('local-name(.)','nvarchar(max)')
    FOR XML PATH(''), TYPE, ROOT('tt')

我在哪里做错了?

【问题讨论】:

  • 我认为不可能保留基于属性的排序。试试看这个msdn.microsoft.com/en-us/library/ms187107(v=sql.90).aspx
  • this link。保留元素的排序顺序,但不保留属性的顺序。有一种叫做“规范 XML”的东西,但问题是:为什么需要它? AFAIC 没有 prettyelegant 方法来实现这一目标......

标签: sql-server xml tsql


【解决方案1】:

不漂亮,但这就是我的想法。

dbFiddle

示例

DECLARE @xml XML = N'
<tt>
    <cpost s="a" cena="0.0000" cpost_id="16385" flprt="1" moq="0" valuta_id="2" nmatr_id="14117" norg_id="1791" />
</tt>'


Declare @S varchar(max) = ''

Select @S = @S + concat(Item,'="',Value,'" ')
 From (
        Select Top 1000 
               Item   = attr.value('local-name(.)','varchar(100)')
              ,Value  = attr.value('.','varchar(max)') 
         From  @XML.nodes('/tt/cpost') as A(r)
         Cross Apply A.r.nodes('./@*') AS B(attr)
         Order By attr.value('local-name(.)','varchar(100)')
      ) A

Select convert(xml,'<tt><cpost '+@S+'/></tt>')

退货

<tt>
  <cpost cena="0.0000" cpost_id="16385" flprt="1" moq="0" nmatr_id="14117" norg_id="1791" s="a" valuta_id="2" />
</tt>

编辑 - 添加内联方法

DECLARE @xml XML = N'
<tt>
    <cpost s="a" cena="0.0000" cpost_id="16385" flprt="1" moq="0" valuta_id="2" nmatr_id="14117" norg_id="1791" />
</tt>'

Select convert(xml,'<tt><cpost '+Stuff((Select  ' ' +concat(Item,'="',Value,'" ')
 From (
        Select Top 1000 
               Item   = attr.value('local-name(.)','varchar(100)')
              ,Value  = attr.value('.','varchar(max)') 
         From  @XML.nodes('/tt/cpost') as A(r)
         Cross Apply A.r.nodes('./@*') AS B(attr)
         Order By attr.value('local-name(.)','varchar(100)')
      ) A
 For XML Path ('')),1,1,'') +'/></tt>')

【讨论】:

  • 不完全是,结果必须是 xml 文件,但像这样:" '"
  • 是的!谢谢!
  • @SashaFes 很高兴它有帮助。我敢肯定一定有更聪明的方法,但现在它逃过了我的视线。
  • @SashaFes 如果需要,我添加了一种内联方法。
  • 嗨,John,可以按字母顺序对属性进行排序,但如果您不将结果存储为字符串,则不会保留。无论您在这里做什么,都不能保证下次以相同的顺序获取属性。在大多数情况下,这样做是为了让 XML 文档在字符串级别上可比较,或者创建一个散列来检查操作。除了属性的顺序之外,也不能保证无关紧要的空格。问题下方的链接文档非常值得阅读......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 2020-03-12
  • 1970-01-01
  • 2020-10-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多