SQL sunucusu eklendiğinde XML yapısını değiştirir


15

SQL sunucusunda bir XML sütununa bazı XML verileri ekliyorum ama veri eklendikten sonra sql sunucusu tarafından değiştirildi. İşte eklediğim veriler

              <xsl:value-of select="name/n/given" />
            <xsl:text> </xsl:text>
          <xsl:value-of select="name/n/family" />

Tekrar okuduğumda şöyle görünüyor

              <xsl:value-of select="name/n/given" />
          <xsl:text />
          <xsl:value-of select="name/n/family" />

İkinci satıra dikkat edin. Bu bir sorundur, çünkü XSLT dönüşüm çıktısının nasıl olacağını değiştirir. İlk örnek verilen ve soyadı arasında bir boşluk yaratırken, ikincisi boşluk yaratmayacak, bu yüzden JohnJohnsen gibi olacak, birincisi John Johnsen gibi olacak.

Bunu çözmenin bir yolu var mı?


Bu bir sorundur, çünkü bu XSLT dönüşüm çıktısının nasıl olacağını değiştirir. İlk satır verilen ve soyadı arasında bir boşluk yaratır, ikincisi arasında herhangi bir boşluk yaratmaz, bu yüzden JohnJohnsen gibi olacak, birincisi John Johnsen gibi olacak
Bay Zach

hmhm, uygun alan "" ama sadece bu yorumdaki gibi bir alan değil (göremezsiniz)
a_vlad

1
Belki de verilerde olmayan ( _veya gibi ~) bir kontrol karakteri kullanabilir ve bunu sunum zamanında bir boşlukla değiştirebilirsiniz.
Aaron Bertrand

Yanıtlar:


25

xml:space = "preserve"Alanı korumak istediğiniz düğümlerde kullanabilirsiniz . Xml: space kullanmak "yalnızca bir niyet sinyalidir" ama SQL sunucusu bize karşı naziktir.

Bir düğüm için

declare @X xml =
'<root>
  <element xml:space = "preserve"> </element>
  <element> </element>
</root>'

select @X;

Sonuç:

<root>
  <element xml:space="preserve"> </element>
  <element />
</root>

Tüm belge:

declare @X xml =
'<root xml:space = "preserve">
  <element> </element>
  <element> </element>
</root>'

select @X;

Sonuç:

<root xml:space="preserve">
  <element> </element>
  <element> </element>
</root>

Belgenin tamamı için başka bir seçenek de 1. stili olan dönüştürmeyi kullanmaktır .

Önemsiz beyaz alanı koruyun. Bu stil ayarı, varsayılan xml: alan işlemeyi xml: space = "preserve" davranışıyla eşleşecek şekilde ayarlar.

declare @X xml = convert(xml, 
'<root>
  <element> </element>
  <element> </element>
</root>', 1)

select @X;

Bunun gerekli olması ilginç. Hangi boşluğun "önemsiz" olduğuna karar vermek ve belge değişiklikleri olmadan sessizce çıkarmak SQL Server'ın görevi olmamalıdır!
Monica ile Hafiflik Yarışları

3
@LightnessRacesinOrbit SQL Server uygulamasından oldukça memnunum. XML'de biçimlendirme (boşluk), siz söyleyene kadar önemli sayılmaz. Belgedeki düğümlerin sayısını ve depolama boyutuna ne yaptığını görmek için bu örneğe bir göz atın ..
Mikael Eriksson

3
Ben bir spec ihlali olarak düşünüyorum, çünkü burada veri XML olarak kabul edilir ve herhangi bir manipülasyon veya dönüşüm veya sadece belgeyi (görünüşte) depolamak dışında başka bir XML katmanı shenanigans formu olmadan XML olarak saklanır, bu nedenle davranış gerekir bir "uygulama" yerine "işlemci" ye düştüğünden, boşluk bırakmamalıdır .
Monica ile Hafiflik Yarışları

9

SQL Server belgelerinin bu sayfasında

Aşağıdaki bilgiler korunmadığından, veriler ... metin metninin özdeş bir kopyası olmayabilir.

Örneğin, sanırım orta etiketin beyaz boşluğunun anlamlı olmadığını ve bu nedenle temsili yeniden düzenlemenin özgür olduğunu düşünüyoruz. Bunun için bir düzeltme olduğunu sanmıyorum; SQL Server XML veri türünü böyle uygular.

Geçici çözüm, @Aaron'un dediği gibi beyaz alan yerine bir yer tutucu kullanmayı içerir. Tüketici bu belirteçleri takmayı ve çıkarmayı unutmamalıdır. Alternatif olarak sütunu XML yerine nvarchar olarak tanımlayın. Bu kesinlikle tüm beyaz alanı ve diğer formatları koruyacaktır. Kısa bir örnek:

create table x(i nvarchar(99), j xml);
insert x values ('<a> </a>', '<a> </a>');  -- note the space
select * from x

i           j
----------  -------
<a> </a>    <a />  

Nvarchar sütunu giriş biçimini korur, XML sütunu korumaz.

SQL sorgularında XPATH kullanma yeteneğini kaybedersiniz. XML yalnızca uygulamada parçalanırsa bu önemsizdir. Ayrıca, karakter dizisi, sizin için önemliyse, DB'de yerden tasarruf sağlayarak sıkıştırılabilir.


XPATH'yi XML sürümüne karşı sorgularda, belki de yeniden biçimlendirmesine izin verseniz bile, oradaki önemsiz alan için bir isabet (veya özledim) güvenmediğiniz sürece kullanabilirsiniz.
Aaron Bertrand

0

CDATAVerileri depolarken alanınızı kapatabilirsiniz:

<xsl:text><![CDATA[ ]]></xsl:text>

SQL Server daha sonra alanı dahili tutar, ancak CDATAkullanarak sonuç alırken gereksiz işaretleme kendisini kaldırır gibi görünüyor SELECT. Neyse ki, böyle bir sonucun yeniden kullanılması sırasında alan korunur SELECT:

DECLARE @X XML = '<text><![CDATA[ ]]></text>'
DECLARE @Y XML

SET @Y = (SELECT @X)

SELECT @Y

Sonuç:

<text> </text>

CDATA da denendi, ancak kaldırıldı.
Bay Zach

@MrZach CDATA'nın kendisi kaldırıldı, ancak alan kaldı. (SQL Express 2016'da çalıştı.)
Bruno

Tuhaf, burada alan kaldırıldı. Ayrıca düşünün 2016 veya 2017'yi ifade edin
Bay Zach
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.