在SQl中使用名称空间解析XML值

时间:2016-09-22 12:25:32

标签: sql xml

我有以下XML:

<ProductionSchedule xmlns:inp2="http://www.wbf.org/xml/B2MML-V0401" xmlns="http://www.wbf.org/xml/B2MML-V0401">
  <inp2:ProductionRequest>
    <inp2:ID>0916A</inp2:ID>
    <inp2:Description>SUBH190916A</inp2:Description>
    <inp2:Location>
      <inp2:EquipmentID>MYEqupiment</inp2:EquipmentID>
    </inp2:Location>
    <inp2:SegmentRequirement>
      <inp2:ID>000</inp2:ID>
      <inp2:EarliestStartTime>2015-10-17T12:00:00</inp2:EarliestStartTime>
      <inp2:LatestEndTime>2015-10-19T12:00:00</inp2:LatestEndTime>
      <inp2:MaterialProducedRequirement>
        <inp2:MaterialDefinitionID>GEEC3MA0025EMZI</inp2:MaterialDefinitionID>
        <inp2:Quantity>
          <inp2:QuantityString>2</inp2:QuantityString>
        </inp2:Quantity>
        <inp2:MaterialProducedRequirementProperty>
          <inp2:ID>ERPWOStatus</inp2:ID>
          <inp2:Value>
            <inp2:ValueString>Released</inp2:ValueString>
          </inp2:Value>
        </inp2:MaterialProducedRequirementProperty>
        <inp2:MaterialProducedRequirementProperty>
          <inp2:ID>ROUTING</inp2:ID>
          <inp2:Value>
            <inp2:ValueString>SOmeMPRVaue</inp2:ValueString>
          </inp2:Value>
        </inp2:MaterialProducedRequirementProperty>
        <inp2:MaterialProducedRequirementProperty>
          <inp2:ID>MPValue2</inp2:ID>
          <inp2:Value>
            <inp2:ValueString>2016-01-21T12:00:00</inp2:ValueString>
          </inp2:Value>
        </inp2:MaterialProducedRequirementProperty>
      </inp2:MaterialProducedRequirement>
    </inp2:SegmentRequirement>
  </inp2:ProductionRequest>
</ProductionSchedule>

我试图从XML中获取值MPValue2。

我尝试了以下内容:

Select `@xml.value('(/ProductionSchedule/inp2:ProductionRequest/inp2:SegmentRequirement/inp2:MaterialProducedRequirement/inp2:MaterialProducedRequirementProperty)[1]','nvarchar(255)')`

1 个答案:

答案 0 :(得分:1)

您的选择没问题,但您必须考虑/声明名称空间:

WITH XMLNAMESPACES(DEFAULT 'http://www.wbf.org/xml/B2MML-V0401'
                  ,'http://www.wbf.org/xml/B2MML-V0401' AS inp2)
Select @xml.value('(/ProductionSchedule/inp2:ProductionRequest/inp2:SegmentRequirement/inp2:MaterialProducedRequirement/inp2:MaterialProducedRequirementProperty)[1]','nvarchar(255)')

这也有效(通配符),但最好尽可能具体:

Select @xml.value('(/*:ProductionSchedule/*:ProductionRequest/*:SegmentRequirement/*:MaterialProducedRequirement/*:MaterialProducedRequirementProperty)[1]','nvarchar(255)')

快速和懒惰也会起作用:-)但在性能方面不快......

Select @xml.value('(//*:MaterialProducedRequirementProperty)[1]','nvarchar(255)')

更新

这是获取所有属性的查询:

WITH XMLNAMESPACES(DEFAULT 'http://www.wbf.org/xml/B2MML-V0401'
                  ,'http://www.wbf.org/xml/B2MML-V0401' AS inp2)
SELECT prop.value('(inp2:ID)[1]','nvarchar(100)') AS Property
FROM @xml.nodes('/ProductionSchedule/inp2:ProductionRequest/inp2:SegmentRequirement/inp2:MaterialProducedRequirement/inp2:MaterialProducedRequirementProperty') AS A(prop)

结果

Property
--------
ERPWOStatus
ROUTING
MPValue2

更新2:在XQuery

中使用ID作为过滤器

了解我如何在XPath .nodes()的末尾添加过滤器。

节点将返回所有子元素 row-wise 。过滤器会将结果集缩减为一行(如果inp2:ID是唯一的!),然后阅读Value/ValueString

我让DEFAULTinp2的名称空间声明。但是,正如@Serf正确指出的那样,两个URL都是相同的。只声明DEFAULT和查询而没有任何名称空间前缀......

就足够了
DECLARE @TheID NVARCHAR(100)='MPValue2';
WITH XMLNAMESPACES(DEFAULT 'http://www.wbf.org/xml/B2MML-V0401'
                  ,'http://www.wbf.org/xml/B2MML-V0401' AS inp2)
SELECT prop.value('(inp2:Value/inp2:ValueString)[1]','nvarchar(100)') AS Property
FROM @xml.nodes('/ProductionSchedule/inp2:ProductionRequest/inp2:SegmentRequirement/inp2:MaterialProducedRequirement/inp2:MaterialProducedRequirementProperty[inp2:ID=sql:variable("@TheID")]') AS A(prop)