2

我正在使用返回属性信息的 API。一些文本信息存储在子节点中,我想将它连接成一个字符串(VARCHAR)。

我的过程是我通过 web 服务获取 xml,然后将其传递给 proc,该 proc 提取 xml 值并将它们插入到视图中,这是我返回的 xml 片段:

<properties>
    <property propertyid="1234">
        <bullets>
            <bullet>nice garden</bullet>
            <bullet>it smells a bit</bullet>
            <bullet>body under the patio</bullet>
        </bullets>
    </property>
    ...
</properties>

这是如何查询 xml 以从中提取值的一瞥:

INSERT        
INTO          VProperty
(             PropertyId,
              Description
)
SELECT        P.value('@propertyid', 'INT'),
              NULL -- extract all the bullet text values into a single string
FROM          @xml.nodes('/properties/property')

在此示例中,我希望能够从 xml 中提取信息,因此最终结果如下:

PropertyId    Description
1234          'nice garden\r\nit smells a bit\r\nbody under the patio

这在纯 sql/xml 中是否可行,或者我是否需要在进入 SQL 领域之前对 xml 执行一些预处理?

非常感谢任何帮助(一如既往)。

4

3 回答 3

5

Does this work for you?

DECLARE @XML XML = 
('<properties>
    <property propertyid="1234">
        <bullets>
            <bullet>nice garden</bullet>
            <bullet>it smells a bit</bullet>
            <bullet>body under the patio</bullet>
        </bullets>
    </property>
    <property propertyid="2345">
        <bullets>
            <bullet>bullet 2345_1</bullet>
            <bullet>bullet 2345_2</bullet>
            <bullet>bullet 2345_3</bullet>
        </bullets>
    </property>
</properties>');

SELECT  X.node.value('@propertyid', 'INT'),
        STUFF((SELECT '\r\n' + B.bullet.value('.', 'NVARCHAR(MAX)')
               FROM   X.node.nodes('./bullets/bullet') B ( bullet )
               FOR XML PATH(''),TYPE).value('.', 'NVARCHAR(MAX)'),
              1, 4, '') AS Description
FROM    @xml.nodes('/properties/property') X ( node );
于 2012-10-21T19:16:09.727 回答
0

您可以使用这个 XQuery(不确定 SQL Server 2008 的 XQuery 方言是否与它完全兼容):

for $pr in /*/property,
    $id in $pr/@propertyid,
    $desc in string-join($pr/*/*, '&#xD;&#xA;')
  return
     (<PropertyId>{string($id)}</PropertyId>,
     <Description>{$desc}</Description>)

使用 Saxon 和 XQSharp (XmlPrime) 在提供的 XML 文档上应用此查询的结果

<properties>
    <property propertyid="1234">
        <bullets>
            <bullet>nice garden</bullet>
            <bullet>it smells a bit</bullet>
            <bullet>body under the patio</bullet>
        </bullets>
    </property>
    ...
</properties>

<PropertyId>1234</PropertyId>
<Description>nice garden&#xD;
it smells a bit&#xD;
body under the patio</Description>
于 2012-10-21T19:27:27.537 回答
0
DECLARE @XML XML
SET @XML = 
'<properties>
  <property propertyid="1234">
    <bullets>
      <bullet>nice garden</bullet>
      <bullet>it smells a bit</bullet>
      <bullet>body under the patio</bullet>
    </bullets>
  </property>
  <property propertyid="2345">
    <bullets>
      <bullet>bullet 2345_1</bullet>
      <bullet>bullet 2345_2</bullet>
      <bullet>bullet 2345_3</bullet>
    </bullets>
  </property>
</properties>'

SET @XML = @XML.query('
    for $prop in /properties/property
    return
    <property propertyid="{string($prop/@propertyid)}">
        <description>
        {
            for $bullet in $prop/bullets[1]/bullet
            return
                if ($bullet is $prop/bullets[1]/bullet[1] and $bullet << $prop/bullets[1]/bullet[last()])
                then concat(string($bullet), "\r\n")
                else
                    if ($bullet is $prop/bullets[1]/bullet[last()])
                    then string($bullet)
                    else concat(string($bullet), "\r\n")
        }    
        </description>
    </property>
')

SELECT
Tab.ColXML.value('@propertyid', 'INTEGER') AS PropertyId,
Tab.ColXML.value('description[1]', 'NVARCHAR(128)') AS Description
FROM @XML.nodes('//property') AS Tab(ColXML)

由于 MS SQL Server 2005 中没有 let 子句,我必须找到解决方法。

在 query() 方法的表达式中,我使用 2 个嵌套的“类似循环”的 for 子句来选择需要的元素。第一个 [for 子句] 构建 [property] 元素。第二个 [for 子句] 从 [bullet] 元素列表中构建 [description] 元素,即 [property] 的子元素。

[description] 将从 [bullet] 元素列表构建的序列中获取值,如下所示:

第一个但不是最后一个 [bullet] 将附加“\r\n”。

非第一个和非最后一个 [bullet] 也将附加“\r\n”。

我们保持其他[子弹]完好无损。

我们连接为每个构建的所有字符串,以便为相关的 [描述] 创造价值。

于 2016-09-16T04:55:05.633 回答