Я извлекаю данные из SQL Server. Один из столбцов - это столбец ntext, в котором есть большой двоичный объект XML. Когда я его извлекаю, он выглядит действительно некрасиво. Есть ли способ отформатировать XML внутри хранимой процедуры SQL Server 2005?

1
AngryHacker 26 Фев 2009 в 22:09
Почему вы пытаетесь поместить презентацию в базу данных? Вместо этого сделайте это в своем клиентском приложении.
 – 
Ken White
17 Май 2019 в 05:40

3 ответа

Лучший ответ

В SQL Server нет функции "сделать это красивее". Однако вы можете сделать это в .NET, поэтому одним из вариантов является настройка функции CLR, которая делает вывод XML красивым. Поскольку это NText, вам придется обрабатывать исключение для любой строки, которая не является XML, или вы получите взрыв.

2
Gregory A Beamer 26 Фев 2009 в 22:15
Нашел хорошее сообщение в блоге о том, как это сделать @ blogs.msdn .com / mrorke / archive / 2005/06/28 / 433471.aspx
 – 
Jared
26 Фев 2009 в 23:11
Интересная запись в блоге. Я не уверен, что буду использовать XSL только для «приведения в порядок», но это очень хороший ресурс. Спасибо, Джаред.
 – 
Gregory A Beamer
27 Фев 2009 в 18:34

Была такая же проблема, просто написал свою функцию:

CREATE FUNCTION LocalCustom.Pretty_XML(@uglyXML VARCHAR(MAX))
RETURNS VARCHAR(MAX) 
AS
BEGIN
  DECLARE @len AS INT = LEN(@uglyXML)
        , @prettyXML AS VARCHAR(MAX) = ''
        , @indent AS INT = 0
        , @tab AS CHAR(1) = CHAR(9)
        , @lf AS CHAR(1) = CHAR(10)
        , @currElement AS VARCHAR(MAX) = NULL
        , @nextElement AS VARCHAR(MAX);

  WHILE @uglyXML + ISNULL(@currElement,'') <> ''
  BEGIN
     IF @currElement IS NULL
     BEGIN
        SET @currElement = LocalCustom.GetColumn(1,'>',@uglyXML);
        SET @uglyXML = SUBSTRING(@uglyXML,LEN(@currElement)+2,@len);
     END;
     SET @nextElement = LocalCustom.GetColumn(1,'>',@uglyXML);
     IF @currElement LIKE '</%'
     BEGIN
        SET @indent = @indent - 1;
        SET @prettyXML = @prettyXML + REPLICATE(@tab,@indent) +  @currElement + '>' + CASE @indent WHEN 0 THEN '' ELSE @lf END;
        SET @currElement = @nextElement;
        SET @uglyXML = SUBSTRING(@uglyXML,LEN(@nextElement)+2,@len);
     END
     ELSE
        IF @currElement LIKE '<% /'
        BEGIN
           SET @prettyXML = @prettyXML + REPLICATE(@tab,@indent) +  @currElement + '>' + CASE @indent WHEN 0 THEN '' ELSE @lf END;
           SET @currElement = @nextElement;
           SET @uglyXML = SUBSTRING(@uglyXML,LEN(@nextElement)+2,@len);
        END
        ELSE
           IF @nextElement LIKE '%</' + SUBSTRING(@currElement,2,@len) 
           BEGIN
              SET @prettyXML = @prettyXML + REPLICATE(@tab,@indent) +  @currElement + '>' + @nextElement + '>' + @lf;
              SET @uglyXML = SUBSTRING(@uglyXML,LEN(@nextElement)+2,@len);
              SET @currElement = NULL;
           END
           ELSE
              IF @nextElement NOT LIKE '</%'
              BEGIN
                 SET @prettyXML = @prettyXML + REPLICATE(@tab,@indent) +  @currElement + '>' + @lf;
                 SET @indent = @indent + 1;
                 SET @currElement = @nextElement;
                 SET @uglyXML = SUBSTRING(@uglyXML,LEN(@nextElement)+2,@len);
              END;
  END;
  RETURN @prettyXML;
END
GO

Вышеупомянутая функция использует уже существующую:

CREATE FUNCTION [LocalCustom].[GetColumn]
(@ColumnNumber INT,
 @Delimiter VARCHAR(32),
 @Record VARCHAR(2000)) 
RETURNS VARCHAR(500)
AS
BEGIN
  DECLARE @ReturnValue VARCHAR(500)
  DECLARE @StartPosition INT
  DECLARE @EndPosition INT
  DECLARE @Counter INT
  -- Find position of first opening delimeter
  IF @ColumnNumber = 1
      SET @StartPosition = 1 - DATALENGTH(@Delimiter)
  ELSE
      BEGIN
      SET @StartPosition = 1
      SET @Counter = 1
      WHILE @StartPosition < LEN(@Record) AND @StartPosition <> 0 AND @Counter < @ColumnNumber 
          BEGIN
          SET @StartPosition = CHARINDEX(@Delimiter,@Record,@StartPosition+1)
          SET @Counter = @Counter + 1
          END
      IF @StartPosition = 0
          SET @StartPosition = LEN(@Record) + 1
      END
  -- Find position of closing delimeter
  SET @EndPosition = CHARINDEX(@Delimiter,@Record,@StartPosition+1)
  IF @EndPosition = 0
      SET @EndPosition = LEN(@Record) + 1
  -- If Valid start and end positions get column
  IF @EndPosition > @StartPosition AND @EndPosition <= LEN(@Record) + 1
      IF @EndPosition - @StartPosition - 1 = 0
          SET @ReturnValue = ''
      ELSE
          SET @ReturnValue = SUBSTRING(@Record, @StartPosition + DATALENGTH(@Delimiter), @EndPosition - @StartPosition - DATALENGTH(@Delimiter))
  ELSE
      SET @ReturnValue = NULL
  -- Strip Carriage Return, Line Feed character
  IF @ReturnValue IS NOT NULL
      BEGIN
      SET @ReturnValue = REPLACE(@ReturnValue,CHAR(10),'')
      SET @ReturnValue = REPLACE(@ReturnValue,CHAR(13),'')
      END
  -- Remove double quotes if used as column delimiter
  IF LEFT(@ReturnValue,1) = '"' AND RIGHT(@ReturnValue,1) = '"'
     BEGIN
     SET @ReturnValue = SUBSTRING(@ReturnValue,2,LEN(@ReturnValue)-2)
     SET @ReturnValue = REPLACE(@ReturnValue,'""','"')
     END
  RETURN @ReturnValue
END
GO
0
Murray Crosswell 17 Май 2019 в 05:32

Это непросто, но если вы ВСТАВИТЕ его с форматированием, sqlserver сохранит форматирование при его извлечении. Форматирование текста в SQL Server довольно сложно, поскольку доступные функции очень ограничены.

0
hova 26 Фев 2009 в 22:13