SQL 中 XML 命名空间的重复
Posted
技术标签:
【中文标题】SQL 中 XML 命名空间的重复【英文标题】:Duplication of XML namespaces in SQL 【发布时间】:2017-12-01 17:50:08 【问题描述】:我有以下问题,我需要删除“cfdi:”的“cfdi_”
我使用命名空间来解决这个问题,但是它们被每个节点重复,我无法消除它们,如果你能帮助我,我将不胜感激
declare @Mydoc xml;
set @Mydoc = (SELECT
'' as importe,
(SELECT Importe, TasaCuota, TipoFactor, Impuesto, Base
FROM CDFIDet
FOR XML RAW('cfdi_traslado'), TYPE, ROOT('cfdi_traslados'))
FROM
CFDIENC
FOR XML RAW('cfdi_gatito'),type)
SELECT @Mydoc;
结果1:
<cfdi:gatito importe="">
<cfdi:traslados>
<cfdi:traslado Importe="1920" TasaCuota="0" TipoFactor="Tasa" Impuesto="16" Base="240" />
<cfdi:traslado Importe="2202" TasaCuota="0" TipoFactor="TASA" Impuesto="16" Base="450" />
</cfdi:traslados>
</cfdi:gatito>
第二次尝试:
declare @Mydoc xml;
WITH xmlnamespaces ('uri' as cfdi)
SELECT @Mydoc = (SELECT
'' AS importe,
(SELECT Importe, TasaCuota, TipoFactor, Impuesto, Base
FROM CDFIDet
FOR XML RAW('cfdi:traslado'), TYPE, ROOT('cfdi:traslados'))
FROM CFDIENC
FOR XML RAW('cfdi:gatito'), TYPE)
SELECT @Mydoc;
结果:
<cfdi:gatito xmlns:cfdi="uri" importe="">
<cfdi:traslados xmlns:cfdi="uri">
<cfdi:traslado Importe="1920" TasaCuota="0" TipoFactor="Tasa" Impuesto="16" Base="240" />
<cfdi:traslado Importe="2202" TasaCuota="0" TipoFactor="TASA" Impuesto="16" Base="450" />
</cfdi:traslados>
</cfdi:gatito>
我的代码比较大,重复次数太多不知道怎么消除
【问题讨论】:
XML 支持高度特定于供应商 - 所以请添加一个标签来指定您是否使用mysql
、postgresql
、sql-server
、oracle
或db2
- 或完全不同的东西。
这是 sql server 但我不会让你放那个标签,因为我还是新手
那么想要的结果是什么?
第一个结果
【参考方案1】:
这是令人讨厌但有效的输出...每个带有FOR XML
语句的子选择都将添加自己的一组命名空间声明。有一个很古老的——但被忽视了! - Microsoft Connect issue去那里投票吧。
没有真正的解决方法,只有一些技巧。大多数人最终在字符串级别上遇到了一些丑陋的技巧。在这种情况下,您可以创建没有任何命名空间的 XML,并在完成后使用字符串方法对其进行更改。
在您的另一个问题中,您有想法将前缀添加到您的别名中,例如 cfdi_Element
并稍后将其更改为 cfdi:Element
。
这正是我要说的......
但再说一遍:这并没有错,只是让你的输出烦人和臃肿......
试试这个: 声明@Mydoc xml;
WITH xmlnamespaces ('uri' as cfdi)
SELECT @Mydoc = (SELECT
'SomeValue' AS OuterElement,
(SELECT 'OtherValue' AS InnerElement
FOR XML RAW('cfdi:traslado'), TYPE)
FOR XML RAW('cfdi:gatito'), TYPE)
--命名空间声明被复制
SELECT @Mydoc;
<cfdi:gatito xmlns:cfdi="uri" OuterElement="SomeValue">
<cfdi:traslado xmlns:cfdi="uri" InnerElement="OtherValue" />
</cfdi:gatito>
--但在这里它“有效”
SELECT @Mydoc = (SELECT
'SomeValue' AS OuterElement,
(SELECT 'OtherValue' AS InnerElement
FOR XML RAW('cfdi_traslado'), TYPE)
FOR XML RAW('cfdi_gatito'), TYPE)
--转换为NVARCHAR(MAX)
,将ns-decl 放入根节点并进行一些替换:
SELECT CAST(REPLACE(REPLACE(CAST(@Mydoc AS NVARCHAR(MAX)),'<cfdi_gatito','<cfdi_gatito xmlns:cfdi="uri"'),'cfdi_','cfdi:') AS XML);
<cfdi:gatito xmlns:cfdi="uri" OuterElement="SomeValue">
<cfdi:traslado InnerElement="OtherValue" />
</cfdi:gatito>
这很丑陋,但通常是唯一的机会......
【讨论】:
你是我的 ECHO 英雄 这更简单,它添加了让我错过真相的节点,你非常感谢,你是我的英雄【参考方案2】:从 XML 预期来看,第二个结果是自给自足的 XML 元素,而第一个结果只能是定义了 cfdi
前缀的命名空间的其他元素的一部分。
所以,我猜所有的作品都如你所定义。
子选择
(SELECT Importe, TasaCuota, TipoFactor, Impuesto, Base
FROM CDFIDet
FOR XML RAW('cfdi:traslado'), TYPE, ROOT('cfdi:traslados'))
产生自给自足的结果
<cfdi:traslados xmlns:cfdi="uri">
<cfdi:traslado Importe="1920" TasaCuota="0" TipoFactor="Tasa" Impuesto="16" Base="240" />
<cfdi:traslado Importe="2202" TasaCuota="0" TipoFactor="TASA" Impuesto="16" Base="450" />
</cfdi:traslados>
因为您定义了ROOT('cfdi:traslados')
- 其中有命名空间,而嵌套元素 cfdi:traslado
位于同一个命名空间中 - 没有单独的命名空间声明。
然后顶部选择:
SELECT
'' AS importe,
(SELECT Importe, TasaCuota, TipoFactor, Impuesto, Base
FROM CDFIDet
FOR XML RAW('cfdi:traslado'), TYPE, ROOT('cfdi:traslados'))
FROM CFDIENC
FOR XML RAW('cfdi:gatito'), TYPE)
将cfdi:traslados
的根元素定义为cfdi:gatito
它有自己的 cfdi
前缀命名空间声明。
我不熟悉 sql-server XML,但是如果你删除会发生什么
ROOT('cfdi:traslados')
来自子选择?
它会从 <cfdi:traslados xmlns:cfdi="uri">
元素中删除 xmlns:cfdi="uri"
吗?
【讨论】:
一个计费的一般一个 xml 和多个需要特定格式的问题,如果我声明名称空间,我对每个节点都有宣传,我需要把所有内容都放在上面,但只替换“cfdi_ " 与 "cfdi:" 对不起,我的问题仍然不清楚...从技术上讲,如果在<cfdi:gatito importe="">
顶部的 Result1 根元素(最近的一个)中将 cfdi
前缀的命名空间声明为 @987654335,则两个结果都是相同的@.
很容易兄弟,看我需要 xsi 出来:schemaLocation 和 xmlns: cfdi 但是使用命名空间我不能声明前缀 xsi 因为 xmlns 是重叠的,除此之外我在每个中生成它节点命名空间被放置,我无法消除以上是关于SQL 中 XML 命名空间的重复的主要内容,如果未能解决你的问题,请参考以下文章