I have the following problem, I need to remove the \"cfdi_\" for \"cfdi:\"
I used the namespaces to solve that but they are duplicated by each node and I can not elimina
It is annoying but valid output... Each sub-select withing a FOR XML
statement will add its own set of namespace declarations. There is a very old - yet ignored! - Microsoft Connect issue Go there and vote for it.
There is no real workaround, just some hacks. Most people end up with some ugly tricks on string level. In this case you create the XML without any namespace and change it with string methods when you are finished.
In your other question you had the idea to add the prefix to your aliases like cfdi_Element
and change this to cfdi:Element
later.
This is exactly what I'm talking about...
But once again: It is not wrong, just annoying and bloating your output...
Try this: declare @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)
--The namespace declaration is replicated
SELECT @Mydoc;
<cfdi:gatito xmlns:cfdi="uri" OuterElement="SomeValue">
<cfdi:traslado xmlns:cfdi="uri" InnerElement="OtherValue" />
</cfdi:gatito>
--But here it "works"
SELECT @Mydoc = (SELECT
'SomeValue' AS OuterElement,
(SELECT 'OtherValue' AS InnerElement
FOR XML RAW('cfdi_traslado'), TYPE)
FOR XML RAW('cfdi_gatito'), TYPE)
--A cast to NVARCHAR(MAX)
, the ns-decl into the root node and some replaces:
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>
This is ugly, but often the only chance...
From XML prospective second result is self-sufficient XML element, while first result can be only part of other element where namespace for cfdi
prefix is defined.
So, I guess all works as you defined.
Sub-select
(SELECT Importe, TasaCuota, TipoFactor, Impuesto, Base
FROM CDFIDet
FOR XML RAW('cfdi:traslado'), TYPE, ROOT('cfdi:traslados'))
produces self-sufficient result as
<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>
because you defined ROOT('cfdi:traslados')
- you have namespace in it, and nested elements cfdi:traslado
are in the same namespace - there is no separate namespace declaration.
Then top select:
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)
defines a root element for cfdi:traslados
as cfdi:gatito
it has its own namespace declaration for cfdi
prefix.
I'm not familiar with sql-server XML, but what will happen if you remove
ROOT('cfdi:traslados')
from sub-select?
Will it remove xmlns:cfdi="uri"
from <cfdi:traslados xmlns:cfdi="uri">
element?