سؤال

I am getting table rows and table data (with HTML tags) from SQL using 'FOR XML'. Is there a way I could assign CSS classes to the html tags in SQL?

What I am currently getting: <tr><td>Name</td><td>Value</td></tr>

SQL query:

SELECT  (SELECT [Name] as [td] FOR XML PATH(''), type),
        (SELECT [Value] as [td] FOR XML PATH(''), type)
FROM    table
FOR XML PATH('tr')

Desired output:

<tr class="test1"> <td class="test2">Name</td> <td class="test3">Value</td> </tr>

هل كانت مفيدة؟

المحلول

I know I am answering my own question, thought it may help someone else.

I'm adding class as an attribute to XML nodes which is giving me the desired output.

SELECT  'test1' AS [@class]
    , ( SELECT  'test2' as [@class]
        , (SELECT 'Name' FOR XML PATH(''))
        FOR XML PATH('td'), type)
    ,(SELECT  'test3' as [@class]
        , (SELECT 'Value' FOR XML PATH(''))
        FOR XML PATH('td'), type) 
FOR XML PATH('tr'), type


Output:
<tr class="test1"><td class="test2">Name</td><td class="test3">Value</td></tr>

نصائح أخرى

Using T-SQL, you can specify an attribute path in the SQL. Relevant MSDN page And you can specify field content to be data in the current row's element with the correct name.

SELECT 'test1' as [@class],
      (SELECT [Name] as [*], 'test2' as [@class] FOR XML PATH('td'), type),
      (SELECT [Value] as [*], 'test3' as [@class] FOR XML PATH('td'), type)
FROM table
FOR XML PATH('tr') 

If at all possible, though, you should have SQL Server produce XML data for you, and then translate it into your HTML need by way of an XSL transformation outside of the server. You'll have cleaner queries, a little less load on your server, and far better seperation of concerns if you do.


T-SQL:

SELECT 
    Name , 
    Value 
FROM table 
FOR XML AUTO

Gets XML like

<table name="name" value="value" />

XSLT:

<xsl:template match="table">
    <tr class="test1">
        <td class="test2">
            <xsl:value-of select="@name" />
        </td>
        <td class="test3">
            <xsl:value-of select="@value" />
        </td>
    </tr>
</xsl:template>

Results in (X)HTML like

<tr class="test1">
    <td class="test2">Name</td>
    <td class="test3">Value</td>
</tr>

I wanted to solve a similar problem in which to create tr classes based on the value of a field, but neither the solution given nor FOR EXPLICIT worked. My project uses Data-Table and a version of Twitter Bootstrap CSS to style HTML tables. Here is the solution that worked for me:

DECLARE @tab varchar(max),
        @header varchar(8000),
        @fields varchar(8000),
        @sql varchar(8000)
DECLARE @rtab TABLE (html varchar(max))

SET @fields = '[field 1], [field 2], [field 3]'

SELECT @sql = 'WITH cte (SELECT * FROM table)
SELECT CAST ((
SELECT CASE 
  WHEN [CriteriaField] = ''Value1'' THEN ''error''
  WHEN [CriteriaField] = ''Value2'' THEN ''success''
  WHEN [CriteriaField] = ''Value3'' THEN ''warning''
  ELSE NULL END
AS [@class], (
SELECT ' + REPLACE(@fields, ',', ' AS td,') + ' AS td' + ' 
FOR XML RAW(''''), ELEMENTS)
FROM cte
FOR XML PATH(''tr'')) AS nvarchar(max))'

INSERT INTO @rtab EXEC(@sql)

SELECT @tab = @tab + REPLACE(REPLACE(REPLACE(REPLACE(html, '&lt;', '<'), '&gt;', '>'), '&amp;gt;', '>'), '&amp;lt;', '<')  --Restore SQL Server's replacement tags.  
SELECT @tab = REPLACE(@tab, '&amp;', '&') --Restore replacement ampersands (anchor links in the data)

SELECT @header = REPLACE(@fields, ',', '</th><th>')
SELECT @header = '<th>' + @header + '</th>'
SELECT @header = '<tr>' + @header + '</tr>'
SELECT @header = REPLACE(REPLACE(@header, '[', ''), ']', '')

SELECT @tab = '<thead>' + @header + '</thead><tbody>' + @tab + '</tbody></table>'
SELECT @tab = '<table id="data-table" class="table table-bordered">' + @tab
SELECT @tab

Use "FOR XML RAW('tr'), ELEMENTS" for the last line in for code, like this:

SELECT [Name] as td, [Value] as td FROM table FOR XML RAW('tr'), ELEMENTS

Thanks

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top