Gerando XML no SQL Server – Arte do FOR XML RAW

FOR XML

Seguindo com a Arte do FOR XML, nos deparamos com o FOR XML RAW, que não se diferencia muito do FOR XML AUTO, mas aproveitamos este artigo para demonstrar outros aspectos interessantes tanto do FOR XML RAW quando do FOR XML AUTO (campos nulos, tipos binários e schemas).

Como primeiro passo, temos uma consulta RAW básica:

SELECT TOP (5)
	  FirstName
	, LastName
FROM
	Person.Contact
FOR XML RAW
<row FirstName="Gustavo" LastName="Achong" />
<row FirstName="Catherine" LastName="Abel" />
<row FirstName="Kim" LastName="Abercrombie" />
<row FirstName="Humberto" LastName="Acevedo" />
<row FirstName="Pilar" LastName="Ackerman" />

Seguida de outra um pouco mais customizada:

SELECT TOP (5)
	  [Name] = FirstName + ', ' + LastName
FROM
	Person.Contact
FOR XML RAW('Contact')
	, ELEMENTS
	, ROOT('Person')
<Person>
  <Contact>
    <Name>Gustavo, Achong</Name>
  </Contact>
  <Contact>
    <Name>Catherine, Abel</Name>
  </Contact>
  <Contact>
    <Name>Kim, Abercrombie</Name>
  </Contact>
  <Contact>
    <Name>Humberto, Acevedo</Name>
  </Contact>
  <Contact>
    <Name>Pilar, Ackerman</Name>
  </Contact>
</Person>

Uma questão importante de se verificar é o comportamento da geração do XML (AUTO e RAW) quando tratamos de campos NULL, assim temos a alternativa de não gerar os nós nulos (comportamento padrão):

SELECT TOP (5)
	  [Name] = FirstName + ', ' + LastName
	, MiddleName
FROM
	Person.Contact
FOR XML RAW('Contact')
	, ELEMENTS ABSENT
	, ROOT('Person')
<Person>
  <Contact>
    <Name>Gustavo, Achong</Name>
  </Contact>
  <Contact>
    <Name>Catherine, Abel</Name>
    <MiddleName>R.</MiddleName>
  </Contact>
  <Contact>
    <Name>Kim, Abercrombie</Name>
  </Contact>
  <Contact>
    <Name>Humberto, Acevedo</Name>
  </Contact>
  <Contact>
    <Name>Pilar, Ackerman</Name>
  </Contact>
</Person>

Ou utilizar XSINIL para que exista uma representação destes nós nulos:

SELECT TOP (5)
	  [Name] = FirstName + ', ' + LastName
	, MiddleName
FROM
	Person.Contact
FOR XML RAW('Contact')
	, ELEMENTS XSINIL 
	, ROOT('Person')
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Contact>
    <Name>Gustavo, Achong</Name>
    <MiddleName xsi:nil="true" />
  </Contact>
  <Contact>
    <Name>Catherine, Abel</Name>
    <MiddleName>R.</MiddleName>
  </Contact>
  <Contact>
    <Name>Kim, Abercrombie</Name>
    <MiddleName xsi:nil="true" />
  </Contact>
  <Contact>
    <Name>Humberto, Acevedo</Name>
    <MiddleName xsi:nil="true" />
  </Contact>
  <Contact>
    <Name>Pilar, Ackerman</Name>
    <MiddleName xsi:nil="true" />
  </Contact>
</Person>

Campos binários também podem ser problemáticos, exemplo o seguinte erro:

SELECT TOP (1)
	ProductPhotoID
	, ThumbNailPhoto
FROM
	Production.ProductPhoto
FOR XML RAW

Msg 6829, Level 16, State 1, Line 1
FOR XML EXPLICIT and RAW modes currently do not support addressing binary data as URLs in column ‘ThumbNailPhoto’. Remove the column, or use the BINARY BASE64 mode, or create the URL directly using the ‘dbobject/TABLE[@PK1=”V1″]/@COLUMN’ syntax.

Assim, utilizamos das declarações BINARY BASE64 para tratar este problema:

SELECT TOP (1)
	ProductPhotoID
	, ThumbNailPhoto
FROM
	Production.ProductPhoto
FOR XML RAW
	, BINARY BASE64
<row ProductPhotoID="1" ThumbNailPhoto="R0lGODlhUAA..." />

Por fim, temos a necessidade de gerar Schemas ou alguma forma de representação dos tipos de dados que estão presentes no XML, onde podemos utilizar do XMLDATA para uma representação simples dos dados:

SELECT TOP (1)
	  [Name] = FirstName + ', ' + LastName
	, [Email] = EmailAddress
FROM
	Person.Contact
FOR XML RAW
	, XMLDATA
<Schema name="Schema2" xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
  <ElementType name="row" content="empty" model="closed">
    <AttributeType name="Name" dt:type="string" />
    <AttributeType name="Email" dt:type="string" />
    <attribute type="Name" />
    <attribute type="Email" />
  </ElementType>
</Schema>
<row xmlns="x-schema:#Schema2" Name="Gustavo, Achong" Email="gustavo0@adventure-works.com" />

Ou XMLSCHEMA, para a declaração mais apropriada com Xml Schema definition language (XSD):

SELECT TOP (1)
	  [Name] = FirstName + ', ' + LastName
	, [Email] = EmailAddress
FROM
	Person.Contact
FOR XML RAW('Contact')
	, ROOT('Person')
	, XMLSCHEMA('PersonContact')
<Person>
  <xsd:schema targetNamespace="PersonContact" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
    <xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
    <xsd:element name="Contact">
      <xsd:complexType>
        <xsd:attribute name="Name" use="required">
          <xsd:simpleType>
            <xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreNonSpace IgnoreKanaType IgnoreWidth" sqltypes:sqlCollationVersion="2">
              <xsd:maxLength value="102" />
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:attribute>
        <xsd:attribute name="Email">
          <xsd:simpleType>
            <xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreNonSpace IgnoreKanaType IgnoreWidth" sqltypes:sqlCollationVersion="2">
              <xsd:maxLength value="50" />
            </xsd:restriction>
          </xsd:simpleType>
        </xsd:attribute>
      </xsd:complexType>
    </xsd:element>
  </xsd:schema>
  <Contact xmlns="PersonContact" Name="Gustavo, Achong" Email="gustavo0@adventure-works.com" />
</Person>
Please follow and like us:

Deixe um comentário

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.