Question

I have a query:

SELECT top 0 * FROM sometable FOR XML AUTO, ELEMENTS, XMLSCHEMA ('MyURI')

This query returns a schema:

<xsd:element name="ClientName">
  <xsd:simpleType>
    <xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
      <xsd:maxLength value="50" /> 
    </xsd:restriction>
  </xsd:simpleType>
</xsd:element>

but I want something more like this:

<xsd:element name="ClientName">
  <xsd:simpleType>
   <xsd:restriction base="xsd:string">
     <xsd:maxLength value="50" /> 
   </xsd:restriction>
  </xsd:simpleType>
</xsd:element>

How can I achieve this?

Was it helpful?

Solution

You can use a XSL transform to change the SQL Server types back to the desired XSD types.

How apply the transform depends on your application. If you are creating static schemata for your tables, then you can use something like Visual Studio or msxsl. If this is a routine request from the server, then Applying an XSL Transformation (SQLXML Managed Classes) may be a better fit.

A style sheet you can build on with additional types is:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
  xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes"
  xmlns="http://www.w3.org/1999/XSL/Transform"
  >
  <xsl:output method="xml" indent="yes"/>
  <xsl:param name="Strip">false</xsl:param>
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@base">
    <xsl:attribute name="{name()}">
      <xsl:choose>
        <xsl:when test=".='sqltypes:nvarchar'">xsd:string</xsl:when>
        <!-- Add additional tests here -->
        <xsl:otherwise>
          <xsl:value-of select="."/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="@sqltypes:*">
    <xsl:if test="$Strip=true">
      <xsl:comment>
        <xsl:text>Stripped (</xsl:text>
        <xsl:value-of select="concat(name(), '=&quot;', ., '&quot;')"/>
        <xsl:text>)</xsl:text>
      </xsl:comment>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

Change the Strip parameter at the beginning to false if you need to see the attributes that are stripped in the transformation process.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top