locked
Clean XML RRS feed

  • Question

  • User962953848 posted

    I have simple webservice in C# to generate XML with product feed for one of my client.

    {
    public SqlConnection con;
    public DataSet ds;
    public string query;
    public SqlCommand sqlcom;
    public XmlReader reader;
    public string xml;
    [WebMethod]
    public DataSet GetProduct()
    {
    con = new SqlConnection(@"Data Source=;Initial Catalog=;Persist Security Info=True;User ID=sa;pwd=;");
    
    query = @"
    select 
    1 as Tag, 
    null as Parent, 
    null as [Katalog!1],
    null as [Produkt!2!NumerKatalogowy!element],
    null as [Produkt!2!Nazwa!Element],
    null as [Produkt!2!NazwaDluga!Element],
    null as [Produkt!2!Opis!CDATA],
    null as [Produkt!2!VAT!Element],
    null as [Produkt!2!EAN!Element],
    null as [Produkt!2!StrukturaTowarowa!Element],
    null as [Produkt!2!Stan!Element],
    null as [Produkt!2!CenaSRP!Element],
    null as [Multimedia!3!Zdjecie_Glowne!element],
    null as [Multimedia!3!Zdjecie_Dodatkowe!element],
    null as [Multimedia!3!Zdjecie_Dodatkowe!element],
    null as [Multimedia!3!Zdjecie_Dodatkowe!element],
    null as [Multimedia!3!Zdjecie_Dodatkowe!element],
    null as [Multimedia!3!Zdjecie_Dodatkowe!element],
    null as [Produkt!2!Producent!Element],
    null as [Produkt!2!Marka!Element],
    null as [Atrybut!4!Waga!Element],
    null as [Atrybut!4!Pasuje_do_modelu!Element],
    null as [Atrybut!4!Gwarancja!Element],
    null as [Atrybut!4!Szerokosc!Element],
    null as [Atrybut!4!Wysokosc!Element],
    null as [Atrybut!4!Głębokosc!Element],
    null as [Atrybut!4!Długosc_kabla!Element],
    null as [Atrybut!4!Natezenie!Element],
    null as [Atrybut!4!Wtyczka_wejsciowa!Element],
    null as [Atrybut!4!Wtyczka_wyjsciowa!Element],
    null as [Atrybut!4!Typ_urzadzenia!Element],
    null as [Atrybut!4!Kompatybilnosc!Element],
    null as [Atrybut!4!Pojemnosc!Element],
    null as [Atrybut!4!Napiecie!Element]
    
    Union all
    /* some selects */
    
    for xml explicit
    
    ";
    sqlcom = new SqlCommand(query, con);
    con.Open();
    ds = new DataSet();
    reader = sqlcom.ExecuteXmlReader();
    ds.ReadXml(reader, XmlReadMode.Auto);
    reader.Close();
    con.Close();
    return ds; 
    }
    }

    This give me XML file, but in header there is **xs:schema** which I have to remove. How can I done it? Change modes of XmlReadMode don't resolve it. Also on each products I have tag **diffgr** which I want to delete too.

    Here is a fragment of XML output I get right now:

    <DataSet xmlns="test">
    <xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="Katalog">
    <xs:element name="Katalog" msdata:IsDataSet="true" msdata:Locale="en-US">
    <xs:complexType>
    <xs:choice minOccurs="0" maxOccurs="unbounded">
    <xs:element name="Produkt">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="NumerKatalogowy" type="xs:string" minOccurs="0"/>
    <xs:element name="Nazwa" type="xs:string" minOccurs="0"/>
    <xs:element name="NazwaDługa" type="xs:string" minOccurs="0"/>
    <xs:element name="Opis" type="xs:string" minOccurs="0"/>
    <xs:element name="VAT" type="xs:string" minOccurs="0"/>
    <xs:element name="EAN" type="xs:string" minOccurs="0"/>
    <xs:element name="StrukturaTowarowa" type="xs:string" minOccurs="0"/>
    <xs:element name="Stan" type="xs:string" minOccurs="0"/>
    <xs:element name="CenaSRP" type="xs:string" minOccurs="0"/>
    <xs:element name="Producent" type="xs:string" minOccurs="0"/>
    <xs:element name="Marka" type="xs:string" minOccurs="0"/>
    <xs:element name="Multimedia" minOccurs="0" maxOccurs="unbounded">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="Zdjęcie_Główne" type="xs:string" minOccurs="0"/>
    <xs:element name="Zdjęcie_Dodatkowe" nillable="true" minOccurs="0" maxOccurs="unbounded">
    <xs:complexType>
    <xs:simpleContent msdata:ColumnName="Zdjęcie_Dodatkowe_Text" msdata:Ordinal="0">
    <xs:extension base="xs:string"> </xs:extension>
    </xs:simpleContent>
    </xs:complexType>
    </xs:element>
    <xs:element name="Atrybut" minOccurs="0" maxOccurs="unbounded">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="Waga" type="xs:string" minOccurs="0"/>
    <xs:element name="Pasuje_do_modelu" type="xs:string" minOccurs="0"/>
    <xs:element name="Gwarancja" type="xs:string" minOccurs="0"/>
    <xs:element name="Szerokość" type="xs:string" minOccurs="0"/>
    <xs:element name="Wysokość" type="xs:string" minOccurs="0"/>
    <xs:element name="Głębokość" type="xs:string" minOccurs="0"/>
    <xs:element name="Długość_kabla" type="xs:string" minOccurs="0"/>
    <xs:element name="Natężenie" type="xs:string" minOccurs="0"/>
    <xs:element name="Wtyczka_wejściowa" type="xs:string" minOccurs="0"/>
    <xs:element name="Wtyczka_wyjściowa" type="xs:string" minOccurs="0"/>
    <xs:element name="Typ_urządzenia" type="xs:string" minOccurs="0"/>
    <xs:element name="Kompatybilność" type="xs:string" minOccurs="0"/>
    <xs:element name="Pojemność" type="xs:string" minOccurs="0"/>
    <xs:element name="Napięcie" type="xs:string" minOccurs="0"/>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:choice>
    </xs:complexType>
    </xs:element>
    </xs:schema>
    <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
    <Katalog xmlns="">
    <Produkt diffgr:id="Produkt1" msdata:rowOrder="0" diffgr:hasChanges="inserted" msdata:hiddenProdukt_Id="0">
    <NumerKatalogowy>449 AMBRER</NumerKatalogowy>
    <Nazwa>Żel antybakteryjny do rąk AMBER 75 % 100 ml </Nazwa>
    <NazwaDługa>Żel antybakteryjny do rąk AMBER 75 % 100 ml </NazwaDługa>
    <Opis>D-panthenol – provitamina B5 jako składnik pielęgnacyjny, intensywnie nawilża, zmiękcza i uelastycznia naskórek. Skutecznie łagodzi podrażnienia, działa kojąco i osłaniającą na skórę.<br/> <br/> Gliceryna o działaniu nawilżającym, a także poprawiającym elastyczność skóry. Żel dzięki wysokiej zawartości alkoholu 75% wykazuje skuteczne działanie antybakteryjne.</Opis>
    <VAT>23.00</VAT>
    <EAN>5906841042276</EAN>
    <Stan>1568</Stan>
    <Multimedia diffgr:id="Multimedia1" msdata:rowOrder="0" diffgr:hasChanges="inserted" msdata:hiddenMultimedia_Id="0" msdata:hiddenProdukt_Id="0">
    <Atrybut diffgr:id="Atrybut1" msdata:rowOrder="0" diffgr:hasChanges="inserted" msdata:hiddenMultimedia_Id="0">
    <Waga>0.300</Waga>
    </Atrybut>
    </Multimedia>
    </Produkt>
    <Produkt diffgr:id="Produkt2" msdata:rowOrder="1" diffgr:hasChanges="inserted" msdata:hiddenProdukt_Id="1">
    <NumerKatalogowy>APEDG05000NEG</NumerKatalogowy>
    <Nazwa>PowerBank Golf Edge 5000 kolor czarny </Nazwa>
    <NazwaDługa>PowerBank Golf Edge 5000 kolor czarny GOLF</NazwaDługa>
    <Opis><h3>PowerBank Golf Edge 5000 kolor czarny</h3> <p>Praktyczne urządzenie w razie wyczerpania się baterii telefonu. Łatwy do przenoszenia - lekki i kompaktowy. Pakiet zawiera kabel USB -> micro USB do łatwego ładowania ze złącza komputera lub innego urządzenia.</p></Opis>
    <VAT>23.00</VAT>
    <EAN>6422505104450</EAN>
    <StrukturaTowarowa>21/18/5/3</StrukturaTowarowa>
    <Stan>31</Stan>
    <CenaSRP>59.9900</CenaSRP>
    <Producent>GOLF</Producent>
    <Marka>GOLF</Marka>
    <Multimedia diffgr:id="Multimedia2" msdata:rowOrder="1" diffgr:hasChanges="inserted" msdata:hiddenMultimedia_Id="1" msdata:hiddenProdukt_Id="1">
    <Zdjęcie_Główne>https://lamelbrands.com/public/assets/produkty/GOLF/APEDG05000NEG.jpg</Zdjęcie_Główne>
    <Zdjęcie_Dodatkowe diffgr:id="Zdjęcie_Dodatkowe1" msdata:rowOrder="0" diffgr:hasChanges="inserted" msdata:hiddenMultimedia_Id="1">https://lamelbrands.com/public/assets/produkty/GOLF/APEDG05000NEG2.jpg</Zdjęcie_Dodatkowe>
    <Atrybut diffgr:id="Atrybut2" msdata:rowOrder="1" diffgr:hasChanges="inserted" msdata:hiddenMultimedia_Id="1">
    <Waga>0.210</Waga>
    <Gwarancja>24 miesiące</Gwarancja>
    <Szerokość>90</Szerokość>
    <Wysokość>178</Wysokość>
    <Głębokość>27</Głębokość>
    <Typ_urządzenia>Li-ion</Typ_urządzenia>
    <Kompatybilność>Uniwersalny</Kompatybilność>
    <Pojemność>5000 mAh</Pojemność>
    <Napięcie>5 V</Napięcie>
    </Atrybut>
    </Multimedia>
    </Produkt>
    </Katalog>




    What I want it to look like:

    <Katalog xmlns="">
    <Produkt>
    <NumerKatalogowy>449 AMBRER</NumerKatalogowy>
    <Nazwa>Żel antybakteryjny do rąk AMBER 75 % 100 ml </Nazwa>
    <NazwaDługa>Żel antybakteryjny do rąk AMBER 75 % 100 ml </NazwaDługa>
    <Opis>D-panthenol – provitamina B5 jako składnik pielęgnacyjny, intensywnie nawilża, zmiękcza i uelastycznia naskórek. Skutecznie łagodzi podrażnienia, działa kojąco i osłaniającą na skórę.<br/> <br/> Gliceryna o działaniu nawilżającym, a także poprawiającym elastyczność skóry. Żel dzięki wysokiej zawartości alkoholu 75% wykazuje skuteczne działanie antybakteryjne.</Opis>
    <VAT>23.00</VAT>
    <EAN>5906841042276</EAN>
    <Stan>1568</Stan>
    <Multimedia >
    <Atrybut >
    <Waga>0.300</Waga>
    </Atrybut>
    </Multimedia>
    </Produkt>
    <Produkt >
    <NumerKatalogowy>APEDG05000NEG</NumerKatalogowy>
    <Nazwa>PowerBank Golf Edge 5000 kolor czarny </Nazwa>
    <NazwaDługa>PowerBank Golf Edge 5000 kolor czarny GOLF</NazwaDługa>
    <Opis><h3>PowerBank Golf Edge 5000 kolor czarny</h3> <p>Praktyczne urządzenie w razie wyczerpania się baterii telefonu. Łatwy do przenoszenia - lekki i kompaktowy. Pakiet zawiera kabel USB -> micro USB do łatwego ładowania ze złącza komputera lub innego urządzenia.</p></Opis>
    <VAT>23.00</VAT>
    <EAN>6422505104450</EAN>
    <StrukturaTowarowa>21/18/5/3</StrukturaTowarowa>
    <Stan>31</Stan>
    <CenaSRP>59.9900</CenaSRP>
    <Producent>GOLF</Producent>
    <Marka>GOLF</Marka>
    <Multimedia>
    <Zdjęcie_Główne>https://lamelbrands.com/public/assets/produkty/GOLF/APEDG05000NEG.jpg</Zdjęcie_Główne>
    <Zdjęcie_Dodatkowe>https://lamelbrands.com/public/assets/produkty/GOLF/APEDG05000NEG2.jpg</Zdjęcie_Dodatkowe>
    <Atrybut >
    <Waga>0.210</Waga>
    <Gwarancja>24 miesiące</Gwarancja>
    <Szerokość>90</Szerokość>
    <Wysokość>178</Wysokość>
    <Głębokość>27</Głębokość>
    <Typ_urządzenia>Li-ion</Typ_urządzenia>
    <Kompatybilność>Uniwersalny</Kompatybilność>
    <Pojemność>5000 mAh</Pojemność>
    <Napięcie>5 V</Napięcie>
    </Atrybut>
    </Multimedia>
    </Produkt>
    </Katalog>
    
    
    

    I searched but didn't found answer for this. Even changed code to work with SqlDataAdapter instead of SqlCommnad but as result DataSet gives schema. I need to remove xs:Schema and diffgr from output XML because my client is unable to parse this XML to get our products in his system.
    Could you help me with fixing this?

    Wednesday, June 17, 2020 8:43 AM

All replies

  • Wednesday, June 17, 2020 2:21 PM
  • User288213138 posted

    Hi lilpri,

    This give me XML file, but in header there is **xs:schema** which I have to remove. How can I done it? Change modes of XmlReadMode don't resolve it. Also on each products I have tag **diffgr** which I want to delete too.

    The XML Namespaces provide a method to avoid element name conflicts. In XML, element names are defined by the developer. This often results in a conflict when trying to mix XML documents from different XML applications.

    If you want to remove namespace from XML with C#, you can try below code:

    //Implemented based on interface, not part of algorithm
    public static string RemoveAllNamespaces(string xmlDocument)
    {
        XElement xmlDocumentWithoutNs = RemoveAllNamespaces(XElement.Parse(xmlDocument));
    
        return xmlDocumentWithoutNs.ToString();
    }
    
    //Core recursion function
     private static XElement RemoveAllNamespaces(XElement xmlDocument)
        {
            if (!xmlDocument.HasElements)
            {
                XElement xElement = new XElement(xmlDocument.Name.LocalName);
                xElement.Value = xmlDocument.Value;
    
                foreach (XAttribute attribute in xmlDocument.Attributes())
                    xElement.Add(attribute);
    
                return xElement;
            }
            return new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el)));
        }

    Best regards,

    Sam

    Thursday, June 18, 2020 6:09 AM
  • User962953848 posted

    Hi samwu,

    Tested this -> But I need to convert DataSet to String/XElement.

    And right after I convert this to String, even without using your code to remove namespaces, I get clean file.

    Its seems like DataSet right after getting data is converting this to look like XML. I prepared some test to look at here: http://serwer.lamel.pl:4599/WebService.asmx/GetProduct

    Thursday, June 18, 2020 8:59 PM