2009-07-13 3 views
3

Следующий фрагмент кода на SQL Server 2005 не будет работать на амперсанд «&»:Использование амперсанд в CAST в SQL

select cast('<name>Spolsky & Atwood</name>' as xml) 

Кто-нибудь знает, обходной путь?

Более подробное объяснение, мне нужно обновить некоторые данные в столбце XML, и я использую поиск & заменить тип взлома, поместив значение XML в varchar, выполнив замену и обновление столбца XML этим приложением.

+0

ли 2005 имеет тип XML, на самом деле? Зачем? –

+1

Что значит «почему»? Чтобы обеспечить синтаксис XML, чтобы разрешить манипуляции с помощью XQuery, чтобы разрешить индексы над XML, разрешить проверку против наборов схем, ... –

ответ

5
select cast('<name>Spolsky &amp; Atwood</name>' as xml) 

Буквальное амперсанд внутри XML тега не допускается стандартом XML, и такой документ не разобрать любой XML анализатор.

XMLSerializer() будет выдавать амперсанд HTML -encoded.

Следующий код:

using System.Xml.Serialization; 

namespace xml 
{ 
    public class MyData 
    { 
     public string name = "Spolsky & Atwood"; 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      new XmlSerializer(typeof(MyData)).Serialize(System.Console.Out, new MyData()); 
     } 
    } 
} 

выведет следующее:

<?xml version="1.0" encoding="utf-8"?> 
<MyData 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <name>Spolsky &amp; Atwood</name> 
</MyData> 

, с &amp; вместо &.

+0

Спасибо. Это работает, но помещает буквальный «&» в xml. Оригинальный XML, который я пытаюсь взломать, был написан XmlSerializer.Serialize(), который сохранил амперсанд как есть в xml. Я хотел бы воспроизвести это (желательно, не перейдя ко всему процессу сериализации снова). – edosoft

+2

Если ваш XML содержит unescaped & -characters, это в основном недействительный XML, и вы действительно должны работать над исправлением этого. –

6

Это недопустимый XML. Используйте &amp;:

select cast('<name>Spolsky &amp; Atwood</name>' as xml) 
+2

Я считаю, что ваш XML-объект «&» был заменен на «&» Stack Overflow. Очень сложно. –

+0

Выглядит нормально. –

+0

Это нормально в коде, но я (возможно, ошибочно) предположил, что вы хотите, чтобы текст читал: «Это недопустимый XML. Используйте« & ». –

3

Вам также понадобится XML, чтобы избежать текста.

Итак, давайте возвращаться назад и предположим, вы строите эту строку как:

SELECT '<name>' + MyColumn + '</name>' FROM MyTable 

вы хотите сделать что-то подобное:

SELECT '<name>' + REPLACE(MyColumn, '&', '&amp;') + '</name>' FROM MyTable 

Конечно, вы вероятно, должны удовлетворять для другие объекты, таким образом:

SELECT '<name>' + REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(MyColumn, '&', '&amp;'), '''', '&apos;'), '"', '&quot;'), '<', '&lt;'), '>', '&gt;') + '</name>' FROM MyTable 
+1

Думая об этом, вы, вероятно, могли бы лучше сыграть в использовании «FOR XML» для генерации XML, а соответствующий XPath для чтения исходного кода, если он уже правильно отформатирован XML, потребует лучшего описания того, re пытается достичь с помощью схемы, чтобы действительно судить –

0

Как Джон и Quassnoi государства, & по себе является недействительно. Это связано с тем, что символ амперсанда является началом символьной сущности - используется для указания символов, которые невозможно представить буквально. Существуют две формы сущности: один указывает символ по имени (например, &amp; или &quot;), а один указывает символ по его коду (я считаю, что это позиция кода в наборе символов Юникода, но не уверен, например, &#34; должен представлять собой двойную кавычку).

Таким образом, чтобы включить литерал & в документ HTML, вы должны указать его сущность: &amp;. Другими распространенными из них могут быть: &lt; для <, &gt; для > и &quot; для ".

3

При работе с XML в SQL вы намного безопаснее использовать встроенные функции вместо того, чтобы преобразовывать его вручную.

Следующий код будет построить правильный SQL переменной XML, который выглядит, как ваш желаемый результат, основанный на сырую строке:

DECLARE @ExampleString nvarchar(40) 
    , @ExampleXml xml 

SELECT @ExampleString = N'Spolsky & Atwood' 

SELECT @ExampleXml = 
    (
     SELECT 'Spolsky & Atwood' AS 'name' 
     FOR XML PATH (''), TYPE 
    ) 

SELECT @ExampleString , @ExampleXml 
+0

Это мертво ручно для преобразования текстового поля в db в XML-вывод, а также, прослушивая меня целую вечность, что –