Как отформатировать XML в SQL Server - PullRequest
1 голос
/ 26 февраля 2009

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

Ответы [ 3 ]

2 голосов
/ 26 февраля 2009

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

0 голосов
/ 16 мая 2019

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

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 голосов
/ 26 февраля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...