Как выбрать значение атрибута xsi: type в SQL Server? - PullRequest
1 голос
/ 19 марта 2010

Учитывая этот XML-документ:

DECLARE @X XML (DOCUMENT search.SearchParameters)  = '<parameters xmlns="http://www.educations.com/Search/Parameters.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <parameter xsi:type="category" categoryID="38" />
</parameters>';

Я хотел бы получить доступ к значению атрибута "тип".

Согласно этому сообщению в блоге , атрибут xsi:type является специальным и недоступен для обычных ключевых слов / функций.

Как я могу это сделать?

PS: я пытался с

WITH XMLNAMESPACES (
 'http://www.educations.com/Search/Parameters.xsd' as p,
 'http://www.w3.org/2001/XMLSchema-instance' as xsi)
  SELECT @X.value('(/p:parameters/p:parameter/@xsi:type)[1]','nvarchar(max)')

но это не сработало.

Ответы [ 2 ]

2 голосов
/ 19 марта 2010

Без указания коллекции, это прекрасно работает для меня:

DECLARE @X XML
SET @x = N' 
<parameters xmlns="http://www.educations.com/Search/Parameters.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 <parameter  xsi:type="category" categoryID="38" />
</parameters>'
;

WITH    XMLNAMESPACES
        (
        'http://www.educations.com/Search/Parameters.xsd' as p,
        'http://www.w3.org/2001/XMLSchema-instance' as xsi
        )
SELECT  @X.value('(/p:parameters/p:parameter/@xsi:type)[1]','nvarchar(max)')

Не могли бы вы опубликовать содержимое search.SearchParameters?

Обновление:

На привязке к схеме XML это кажется невозможным.

Вы можете привести свой столбец к свободному типу XML:

WITH    XMLNAMESPACES
        (
        'http://www.educations.com/Search/Parameters.xsd' as p,
        'http://www.w3.org/2001/XMLSchema-instance' as xsi
        )
SELECT  CAST(@X AS XML).value('(/p:parameters/p:parameter/@xsi:type)[1]','nvarchar(max)')

(но вы не будетеможет использовать XML индексы любого из ваших столбцов) или выполнить логическую проверку для определенного типа:

WITH XMLNAMESPACES
        (
        'http://www.educations.com/Search/Parameters.xsd' as p
        )
SELECT @X.query('(/p:parameters/p:parameter)[1] instance of element(*, p:category?)')
0 голосов
/ 21 января 2017

Я знаю, что это старый вопрос, однако я вчера столкнулся с этой проблемой и не нашел очевидного ответа на это ограничение в SQL.Однако, если у вас есть контроль над схемой, я определил обходной путь.

Просто создайте атрибут для каждого подтипа с тем же именем (widgetType в моем примере ниже).

Установите каждый атрибутк простому типу xsi: string и наложите на него ограничение, чтобы единственным значением было имя вашего подтипа.Кроме того, установите его в качестве значения по умолчанию для атрибута.

Если вы свяжете эту схему со столбцом данных xml, вы всегда сможете запросить этот атрибут, который по существу отражает значение xsi: type.

Я признаю, что это не идеально, но это лучше, чем приведение значения как нетипизированного и потеря преимуществ ваших индексов.

Вот пример:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd"
           elementFormDefault="qualified"
           xmlns="http://tempuri.org/XMLSchema.xsd"
           xmlns:mstns="http://tempuri.org/XMLSchema.xsd"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="widget"
              type="baseWidget" />
  <xs:complexType name="baseWidget"
                  abstract="true"></xs:complexType>
  <xs:complexType name="widgetA">
    <xs:complexContent>
      <xs:extension base="baseWidget">
        <xs:attribute name="widgetType"
                      default="widgetA">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="widgetA" />
            </xs:restriction>
          </xs:simpleType>
        </xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
  <xs:complexType name="widgetB">
    <xs:complexContent>
      <xs:extension base="baseWidget">
        <xs:attribute name="widgetType"
                      default="widgetB">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="widgetB" />
            </xs:restriction>
          </xs:simpleType>
        </xs:attribute>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:schema>

Если выЕсли поместить запись XML в таблицу, привязанную к этой схеме без атрибута widgetType, SQL автоматически добавит ее из-за значения по умолчанию.Для вас всегда будет доступен запрос.

<?xml version="1.0" encoding="utf-8"?>
<widget xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:type="widgetA"
        widgetType="widgetA"
        xmlns="http://tempuri.org/XMLSchema.xsd" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...