Nan0
Nan0

Reputation: 61

Delete xmlns namespace from XML file

I would like to remove the first xmlns attribute from a XML file because it's causing me some trouble in my XSL transformation.

Here's the original xml :

<ns4:ExportReferences xmlns="urn:be:fgov:ehealth:samws:v2:refdata" xmlns:ns2="urn:be:fgov:ehealth:samws:v2:core" xmlns:ns3="urn:be:fgov:ehealth:samws:v2:consultation" xmlns:ns4="urn:be:fgov:ehealth:samws:v2:export">
  <AtcClassification code="A">
    <Description>Alimentary Tract and Metabolism</Description>
  </AtcClassification>
  <AtcClassification code="A01">
    <Description>Stomatological Preparations</Description>
  </AtcClassification>
</ns4:ExportReferences>

I first tried with a Regex : Regex.IsMatch(xml, @"xmlns=(.*?)") gives me a true but Regex.Replace(xml, pattern, "") don't works.

Then i tried to delete it with :

XDocument doc = XDocument.Load(@"file.xml");
foreach (var attr in doc.Descendants().Attributes()){
  if (attr.Name == "xmlns")
    attr.Remove();}

And a lot of other tries but i always have the same behavior that i don't understand : I can delete the first xmlns attribute but when i save the file it appears now in every elements :

<ns4:ExportReferences xmlns="urn:be:fgov:ehealth:samws:v2:refdata" xmlns:ns2="urn:be:fgov:ehealth:samws:v2:core" xmlns:ns3="urn:be:fgov:ehealth:samws:v2:consultation" xmlns:ns4="urn:be:fgov:ehealth:samws:v2:export">
  <AtcClassification code="A" xmlns="urn:be:fgov:ehealth:samws:v2:refdata">
    <Description>Alimentary Tract and Metabolism</Description>
  </AtcClassification>
  <AtcClassification code="A01" xmlns="urn:be:fgov:ehealth:samws:v2:refdata">
    <Description>Stomatological Preparations</Description>
  </AtcClassification>
</ns4:ExportReferences>

If i save it and make a second try with :

foreach (var attr in doc.Descendants().Attributes()){
  if (attr.NextAttribute != null && attr.NextAttribute.Name == "xmlns")
    attr.NextAttribute.Remove();}

It removes it as well but no changes made when reopening the file.

Any helps would be really appreciated.

EDIT providing more infos :

  1. Input XML :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns4:ExportReferences xmlns="urn:be:fgov:ehealth:samws:v2:refdata" xmlns:ns2="urn:be:fgov:ehealth:samws:v2:core" xmlns:ns3="urn:be:fgov:ehealth:samws:v2:consultation" xmlns:ns4="urn:be:fgov:ehealth:samws:v2:export" xmlns:ns5="urn:be:fgov:ehealth:samws:v2:actual:common" xmlns:ns6="urn:be:fgov:ehealth:samws:v2:company:submit" xmlns:ns7="urn:be:fgov:ehealth:samws:v2:reimbursement:submit" xmlns:ns8="urn:be:fgov:ehealth:samws:v2:reimbursementlaw:submit" xmlns:ns9="urn:be:fgov:ehealth:samws:v2:virtual:common" xmlns:ns10="urn:be:fgov:ehealth:samws:v2:compounding:common" xmlns:ns11="urn:be:fgov:ehealth:samws:v2:nonmedicinal:common" xmlns:ns12="urn:be:fgov:ehealth:samws:v2:chapteriv:submit" xmlns:ns13="urn:be:fgov:ehealth:samws:v2:actual:status" version="5.0" SamId="E.20201119_141847">
    <AtcClassification code="A">
        <Description>Alimentary Tract and Metabolism</Description>
    </AtcClassification>
    <AtcClassification code="A01">
        <Description>Stomatological Preparations</Description>
    </AtcClassification>
    <AtcClassification code="A01A">
        <Description>Stomatological Preparations</Description>
    </AtcClassification>
    <AtcClassification code="A01AA">
        <Description>Caries Prophylactic Agents</Description>
    </AtcClassification>
    <AtcClassification code="A01AA01">
        <Description>Sodium Fluoride</Description>
    </AtcClassification>
    <AtcClassification code="A01AA02">
        <Description>Sodium Monofluorophosphate</Description>
    </AtcClassification>
</ns4:ExportReferences>
  1. XSLT :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns2="urn:be:fgov:ehealth:samws:v2:core"
xmlns:ns3="urn:be:fgov:ehealth:samws:v2:consultation"
xmlns:ns4="urn:be:fgov:ehealth:samws:v2:export"
xmlns:ns5="urn:be:fgov:ehealth:samws:v2:actual:common"
xmlns:ns6="urn:be:fgov:ehealth:samws:v2:company:submit"
xmlns:ns7="urn:be:fgov:ehealth:samws:v2:reimbursement:submit"
xmlns:ns8="urn:be:fgov:ehealth:samws:v2:reimbursementlaw:submit"
xmlns:ns9="urn:be:fgov:ehealth:samws:v2:virtual:common"
xmlns:ns10="urn:be:fgov:ehealth:samws:v2:compounding:common"
xmlns:ns11="urn:be:fgov:ehealth:samws:v2:nonmedicinal:common"
xmlns:ns12="urn:be:fgov:ehealth:samws:v2:chapteriv:submit"
xmlns:ns13="urn:be:fgov:ehealth:samws:v2:actual:status">
<xsl:template match="/ns4:ExportReferences">
  <xsl:for-each select="AtcClassification">
    <xsl:text>INSERT INTO ATC VALUES ('</xsl:text>
      <xsl:value-of select="@code" />
      <xsl:text>','</xsl:text>
        <xsl:value-of select="Description" />
      <xsl:text>');</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>
  1. Desired output :
INSERT INTO ATC VALUES ('A','Alimentary Tract and Metabolism');INSERT INTO ATC VALUES ('A01','Stomatological Preparations');INSERT INTO ATC VALUES ('A01A','Stomatological Preparations');INSERT INTO ATC VALUES ('A01AA','Caries Prophylactic Agents');INSERT INTO ATC VALUES ('A01AA01','Sodium Fluoride');INSERT INTO ATC VALUES ('A01AA02','Sodium Monofluorophosphate');
  1. XSLT processor and its version :

xsl:vendor = Microsoft xsl:version = 1

Upvotes: 0

Views: 1305

Answers (2)

Yitzhak Khabinsky
Yitzhak Khabinsky

Reputation: 22301

I seems that there is no need in XSLT, dynamic SQL, or anything else.

It is possible to do it directly on the database side in SQL Server. It is very easy to handle namespaces there.

T-SQL

DECLARE @tbl_atc TABLE (code VARCHAR(10), Description VARCHAR(100));
DECLARE @xml XML =
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns4:ExportReferences xmlns="urn:be:fgov:ehealth:samws:v2:refdata"
                      xmlns:ns2="urn:be:fgov:ehealth:samws:v2:core"
                      xmlns:ns3="urn:be:fgov:ehealth:samws:v2:consultation"
                      xmlns:ns4="urn:be:fgov:ehealth:samws:v2:export"
                      xmlns:ns5="urn:be:fgov:ehealth:samws:v2:actual:common"
                      xmlns:ns6="urn:be:fgov:ehealth:samws:v2:company:submit"
                      xmlns:ns7="urn:be:fgov:ehealth:samws:v2:reimbursement:submit"
                      xmlns:ns8="urn:be:fgov:ehealth:samws:v2:reimbursementlaw:submit"
                      xmlns:ns9="urn:be:fgov:ehealth:samws:v2:virtual:common"
                      xmlns:ns10="urn:be:fgov:ehealth:samws:v2:compounding:common"
                      xmlns:ns11="urn:be:fgov:ehealth:samws:v2:nonmedicinal:common"
                      xmlns:ns12="urn:be:fgov:ehealth:samws:v2:chapteriv:submit"
                      xmlns:ns13="urn:be:fgov:ehealth:samws:v2:actual:status"
                      version="5.0" SamId="E.20201119_141847">
    <AtcClassification code="A">
        <Description>Alimentary Tract and Metabolism</Description>
    </AtcClassification>
    <AtcClassification code="A01">
        <Description>Stomatological Preparations</Description>
    </AtcClassification>
    <AtcClassification code="A01A">
        <Description>Stomatological Preparations</Description>
    </AtcClassification>
    <AtcClassification code="A01AA">
        <Description>Caries Prophylactic Agents</Description>
    </AtcClassification>
    <AtcClassification code="A01AA01">
        <Description>Sodium Fluoride</Description>
    </AtcClassification>
    <AtcClassification code="A01AA02">
        <Description>Sodium Monofluorophosphate</Description>
    </AtcClassification>
</ns4:ExportReferences>';

;WITH XMLNAMESPACES(DEFAULT 'urn:be:fgov:ehealth:samws:v2:refdata'
    , 'urn:be:fgov:ehealth:samws:v2:export' AS ns4) --, rs AS
INSERT INTO @tbl_atc
SELECT c.value('@code', 'VARCHAR(30)') AS code
    , c.value('(Description/text())[1]', 'VARCHAR(100)') AS [Description]
FROM @xml.nodes('/ns4:ExportReferences/AtcClassification') AS t(c);

-- test
SELECT * FROM @tbl_atc;

Upvotes: 1

Damien_The_Unbeliever
Damien_The_Unbeliever

Reputation: 239794

So you should just need to add that namespace into your XSL too:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns2="urn:be:fgov:ehealth:samws:v2:core"
xmlns:ns3="urn:be:fgov:ehealth:samws:v2:consultation"
xmlns:ns4="urn:be:fgov:ehealth:samws:v2:export"
xmlns:ns5="urn:be:fgov:ehealth:samws:v2:actual:common"
xmlns:ns6="urn:be:fgov:ehealth:samws:v2:company:submit"
xmlns:ns7="urn:be:fgov:ehealth:samws:v2:reimbursement:submit"
xmlns:ns8="urn:be:fgov:ehealth:samws:v2:reimbursementlaw:submit"
xmlns:ns9="urn:be:fgov:ehealth:samws:v2:virtual:common"
xmlns:ns10="urn:be:fgov:ehealth:samws:v2:compounding:common"
xmlns:ns11="urn:be:fgov:ehealth:samws:v2:nonmedicinal:common"
xmlns:ns12="urn:be:fgov:ehealth:samws:v2:chapteriv:submit"
xmlns:ns13="urn:be:fgov:ehealth:samws:v2:actual:status"

xmlns:something="urn:be:fgov:ehealth:samws:v2:refdata">

<xsl:template match="/ns4:ExportReferences">

  <xsl:for-each select="something:AtcClassification">

    <xsl:text>INSERT INTO ATC VALUES ('</xsl:text>
      <xsl:value-of select="@code" />
      <xsl:text>','</xsl:text>

        <xsl:value-of select="something:Description" />

      <xsl:text>');</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Notice: The ActClassification element, because it has no prefix in the XML is in the default namespace. Since it's inside another element that declares the default namespace to be urn:be:fgov:ehealth:samws:v2:refdata, that's what it is.

Note, also, that namespace prefixes have local meanings. There's no need for you to use ns2 in your transform just because the XML file uses ns2; It's the urn that matters/needs to match. So here I've pulled in the urn:be:fgov:ehealth:samws:v2:refdata with the prefix something.

Upvotes: 1

Related Questions