C # ile XML'den tüm ad alanları nasıl kaldırılır?


104

Ad alanlarını tüm XML öğelerinden kaldırmak için temiz, zarif ve akıllı bir çözüm arıyorum. Bunu yapmak nasıl bir işlev görür?

Tanımlanmış arayüz:

public interface IXMLUtils
{
        string RemoveAllNamespaces(string xmlDocument);
}

NS'nin kaldırılacağı örnek XML:

<?xml version="1.0" encoding="utf-16"?>
<ArrayOfInserts xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <insert>
    <offer xmlns="http://schema.peters.com/doc_353/1/Types">0174587</offer>
    <type2 xmlns="http://schema.peters.com/doc_353/1/Types">014717</type2>
    <supplier xmlns="http://schema.peters.com/doc_353/1/Types">019172</supplier>
    <id_frame xmlns="http://schema.peters.com/doc_353/1/Types" />
    <type3 xmlns="http://schema.peters.com/doc_353/1/Types">
      <type2 />
      <main>false</main>
    </type3>
    <status xmlns="http://schema.peters.com/doc_353/1/Types">Some state</status>
  </insert>
</ArrayOfInserts>

RemoveAllNamespaces (xmlWithLotOfNs) çağrıldıktan sonra şunu almalıyız:

  <?xml version="1.0" encoding="utf-16"?>
    <ArrayOfInserts>
      <insert>
        <offer >0174587</offer>
        <type2 >014717</type2>
        <supplier >019172</supplier>
        <id_frame  />
        <type3 >
          <type2 />
          <main>false</main>
        </type3>
        <status >Some state</status>
      </insert>
    </ArrayOfInserts>

Tercih edilen çözüm dili .NET 3.5 SP1'de C # 'dır.


@JohnSaunders: Haklısınız. Ama bu özel durumda bazı sistem entegrasyonu yapmam gerekiyor. Ve o zamanlar tek seçenek buydu.
Peter Stegnar

@PeterStegnar hata genellikle eski biçimleri oluşturan bilgisayar korsanıdır. Genellikle, geliştiriciler xml'yi kronik olarak kötüye kullanır. Bir kenara atılacak ilk çılgın önemli özellik isim alanlarıdır.
Gusdor

Yanıtlar:


103

İşte son cevap. Harika Jimmy fikrini kullandım (bu maalesef kendi kendine tamamlanmadı) ve düzgün çalışması için özyineleme işlevini tamamladım.

Arayüze göre:

string RemoveAllNamespaces(string xmlDocument);

Burada XML ad alanlarını kaldırmak için son temiz ve evrensel C # çözümünü temsil ediyorum:

//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)));
    }

% 100 çalışıyor, ancak pek test etmedim, bu yüzden bazı özel durumları kapsamayabilir ... Ama başlamak için iyi bir temel.


8
Bu, ad alanlarına sahip özelliklerle ne kadar iyi çalışır? Aslında, kodunuz nitelikleri tamamen yok sayar.
John Saunders

6
Ad alanlarının bazı uygulamalarda yararlı olabileceğini, ancak benimkinde hiç olmadığını biliyorum; büyük bir sıkıntıya neden oluyorlardı. Bu çözüm benim için çalıştı.
JYelton

@John Saunders - Evet bu çözümü kullandım ve haklı olduğunu anladım. Cevap olarak güncellenmiş bir çözüm yayınlıyorum
Konrad Morawski

6
Kod, ad alanlarının yanı sıra tüm nitelikleri de kaldırdığı için bu çözüm benim için işe yaramadı. Elbette, kaldırılan özniteliğin bir ad alanı veya öznitelik olup olmadığını görmek için birkaç değişiklik işe yarayabilir
bigfoot

@KonradMorawski, maalesef cevabını burada göremiyorum. :(
Rami A.

63

Etiketli en kullanışlı yanıtın iki kusuru vardır:

  • Öznitelikleri yok sayar
  • "Karma mod" öğeleriyle çalışmaz

İşte bu konudaki görüşüm:

 public static XElement RemoveAllNamespaces(XElement e)
 {
    return new XElement(e.Name.LocalName,
      (from n in e.Nodes()
        select ((n is XElement) ? RemoveAllNamespaces(n as XElement) : n)),
          (e.HasAttributes) ? 
            (from a in e.Attributes() 
               where (!a.IsNamespaceDeclaration)  
               select new XAttribute(a.Name.LocalName, a.Value)) : null);
  }          

Örnek kod burada .


Ne yazık ki bu benim için işe yaramadı, girilen aynı xml iade edildi. :(
Rami A.

@RamiA. sorunun ne olduğunu görebilmemiz için kodun bir parçasını gönderebilir misiniz?
Dexter Legaspi

Benim için de işe yaramadı. Sanırım öznitelikleri kopyaladığınız için, xmlnsaynı zamanda kopyalamış oluyorsunuz .
MarioDS

1
Bu çalışıyor. Onu kullandım ... ancak ad alanını tanımlayan gerçek xmlns özniteliklerini kaldırmaması anlamında kapsamlı bir temizlik olmadığını fark ettim ... bu yüzden sadece bunu yapmak için güncelledim ... ve bir özet örneği ekledim .
Dexter Legaspi

(from a in e.Attributes().DistinctBy(x => x.Name.LocalName)Dava için eklemeniz gerekiyorlang=""ru-ru"" xml:lang=""ru-ru""
smg

26

LINQ kullanarak zorunlu cevap:

static XElement stripNS(XElement root) {
    return new XElement(
        root.Name.LocalName,
        root.HasElements ? 
            root.Elements().Select(el => stripNS(el)) :
            (object)root.Value
    );
}
static void Main() {
    var xml = XElement.Parse(@"<?xml version=""1.0"" encoding=""utf-16""?>
    <ArrayOfInserts xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
      <insert>
        <offer xmlns=""http://schema.peters.com/doc_353/1/Types"">0174587</offer>
        <type2 xmlns=""http://schema.peters.com/doc_353/1/Types"">014717</type2>
        <supplier xmlns=""http://schema.peters.com/doc_353/1/Types"">019172</supplier>
        <id_frame xmlns=""http://schema.peters.com/doc_353/1/Types"" />
        <type3 xmlns=""http://schema.peters.com/doc_353/1/Types"">
          <type2 />
          <main>false</main>
        </type3>
        <status xmlns=""http://schema.peters.com/doc_353/1/Types"">Some state</status>
      </insert>
    </ArrayOfInserts>");
    Console.WriteLine(stripNS(xml));
}

3
Sanırım VB milletine C # dilinde bir XML hazır bilgisine sahip olabileceğinizi gösterebilirsiniz.
Robert Harvey

1
@Robert, bu bir XML değişmezi değil. Bu bir dizedir. Arada büyük bir fark var!
CoderDennis

Jimmy, yakınsın ama henüz orada değil. :) Fikrinize göre nihai çözüm yazıyorum. Oraya göndereceğim.
Peter Stegnar

haklısın :) siz oradayken, düzeltmenin kendi versiyonunu sunuyorum.
Jimmy

3
Bu, yalnızca ad alanlarını değil, tüm öznitelikleri çıkarır. Florian'ın cevabını görünDüzeltmek için .
Brian

25

Bu hile yapacak :-)

foreach (XElement XE in Xml.DescendantsAndSelf())
{
    // Stripping the namespace by setting the name of the element to it's localname only
    XE.Name = XE.Name.LocalName;
    // replacing all attributes with attributes that are not namespaces and their names are set to only the localname
    XE.ReplaceAttributes((from xattrib in XE.Attributes().Where(xa => !xa.IsNamespaceDeclaration) select new XAttribute(xattrib.Name.LocalName, xattrib.Value)));
}

Bu harika çalışıyor, sadece çalışmakla kalmıyor, aynı zamanda DescendantAndself yöntemini kullanarak verileri yazdığı dosyayı da Xelement'i etkilemiyor. teşekkürler dostum!
shawn

benim için çalışıyor. Ayrıca, diğer çözümlerin yol boyunca gevşek olduğu CDATA'yı da işler.
paul

16

C # 'da tekrar seçin - öznitelikleri kopyalamak için satır eklendi:

    static XElement stripNS(XElement root)
    {
        XElement res = new XElement(
            root.Name.LocalName,
            root.HasElements ?
                root.Elements().Select(el => stripNS(el)) :
                (object)root.Value
        );

        res.ReplaceAttributes(
            root.Attributes().Where(attr => (!attr.IsNamespaceDeclaration)));

        return res;
    }

1
Kök öğe için çalışır, ancak yuvalanmış öğeler için geçerli değildir; ad alanları, belki XElement.ToString () tarafından otomatik olarak yeniden adlandırılmış gibi görünüyor.
Rami A.

Tam olarak tüm ad alanlarını kaldırmak, ancak nitelikleri korumak için ihtiyacım olan şey.
Bassie

10

XSLT kullanarak zorunlu cevap:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="no" encoding="UTF-8"/>

  <xsl:template match="/|comment()|processing-instruction()">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

"Zorunlu" için +1. :-) Ad alanlarını kaldırmanın neden akıllıca bir karar olduğunu hala merak ediyorum. Bu muhtemelen çöker ve <element ns: attr = "a" attr = "b" /> üzerinde yanar.
Tomalak

Elbette, ancak her NS kaldırma tekniği az ya da çok olacaktır. Geçerlilik ya da geçerlilik, size nerede ihtiyacım olduğunu söyleyebilirim: üçüncü taraf XML'i içe aktararak geçerli bir XSD'yi sıralayamazlar, ancak ad aralığı konusunda ısrar ederler. Nihayetinde pratiklik kuralları.
annakata

1
@annakata: Çözüm düşündüğünüzden daha basit. Etkinleştirmeyi durdurun. XML'i anlamayan herhangi bir tekniği kullanmayı reddedin. Hala bu tür çöpleri kullanmaya zorlanmamızın tek nedeni, insanların biraz daha sık "hayır" demeleri gerektiğinde "evet" demeye devam etmeleridir. Standartlar 10 yaşın üzerindedir! Var olmasını sağlamaya devam etmemiz dışında neden hala XML Ad Alanlarını anlamayan bir yazılıma sahibiz?
John Saunders

3
@John - ha, yapılması gerekenler var ve yönetimin yapılacağını düşündüğü şeyler var. Her şey, mümkün olan tüm dünyaların en iyisi için en iyisidir.
annakata

1
@Tomalak bir kullanım durumu, JSON'a dönüştürmeniz gerekiyorsa ve ad alanı bildirimleri bu işleme müdahale ederse olabilir.
devlord

10

Ve bu, XSI öğelerini de kaldıracak mükemmel bir çözümdür. (Xmlns'yi kaldırırsanız ve XSI'yi kaldırmazsanız, .Net size bağırır ...)

string xml = node.OuterXml;
//Regex below finds strings that start with xmlns, may or may not have :and some text, then continue with =
//and ", have a streach of text that does not contain quotes and end with ". similar, will happen to an attribute
// that starts with xsi.
string strXMLPattern = @"xmlns(:\w+)?=""([^""]+)""|xsi(:\w+)?=""([^""]+)""";
xml = Regex.Replace(xml, strXMLPattern, "");

1
Bunu 2 saat önce okumalıyım. Neredeyse aynı normal
ifadeyi yaptı

Yine de örneğin <xxx: tagname> gibi öğeleri temizlemeniz gerekebileceğini unutmayın. Aşağıdaki kodu kullandım (sorumluluk reddi, makinemde çalışıyor): Regex.Replace(xmlStr, @"<(/?)([^>\s:]+):([^>]+)>", "<$1$3>")
Edwin

9

Bu sorunun sözde çözüldüğünü biliyorum, ancak uygulanma şeklinden tamamen memnun değildim. Burada MSDN bloglarında XmlTextWriter, ad alanlarını kaldıran geçersiz kılınmış bir sınıfa sahip başka bir kaynak buldum . Oldukça biçimlendirme ve kök öğeyi koruma gibi istediğim diğer şeyleri elde etmek için biraz ince ayar yaptım. İşte şu anda projemde bulunanlar.

http://blogs.msdn.com/b/kaevans/archive/2004/08/02/206432.aspx

Sınıf

/// <summary>
/// Modified XML writer that writes (almost) no namespaces out with pretty formatting
/// </summary>
/// <seealso cref="http://blogs.msdn.com/b/kaevans/archive/2004/08/02/206432.aspx"/>
public class XmlNoNamespaceWriter : XmlTextWriter
{
    private bool _SkipAttribute = false;
    private int _EncounteredNamespaceCount = 0;

    public XmlNoNamespaceWriter(TextWriter writer)
        : base(writer)
    {
        this.Formatting = System.Xml.Formatting.Indented;
    }

    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        base.WriteStartElement(null, localName, null);
    }

    public override void WriteStartAttribute(string prefix, string localName, string ns)
    {
        //If the prefix or localname are "xmlns", don't write it.
        //HOWEVER... if the 1st element (root?) has a namespace we will write it.
        if ((prefix.CompareTo("xmlns") == 0
                || localName.CompareTo("xmlns") == 0)
            && _EncounteredNamespaceCount++ > 0)
        {
            _SkipAttribute = true;
        }
        else
        {
            base.WriteStartAttribute(null, localName, null);
        }
    }

    public override void WriteString(string text)
    {
        //If we are writing an attribute, the text for the xmlns
        //or xmlns:prefix declaration would occur here.  Skip
        //it if this is the case.
        if (!_SkipAttribute)
        {
            base.WriteString(text);
        }
    }

    public override void WriteEndAttribute()
    {
        //If we skipped the WriteStartAttribute call, we have to
        //skip the WriteEndAttribute call as well or else the XmlWriter
        //will have an invalid state.
        if (!_SkipAttribute)
        {
            base.WriteEndAttribute();
        }
        //reset the boolean for the next attribute.
        _SkipAttribute = false;
    }

    public override void WriteQualifiedName(string localName, string ns)
    {
        //Always write the qualified name using only the
        //localname.
        base.WriteQualifiedName(localName, null);
    }
}

Kullanım

//Save the updated document using our modified (almost) no-namespace XML writer
using(StreamWriter sw = new StreamWriter(this.XmlDocumentPath))
using(XmlNoNamespaceWriter xw = new XmlNoNamespaceWriter(sw))
{
    //This variable is of type `XmlDocument`
    this.XmlDocumentRoot.Save(xw);
}

1
Cevabınız bir hack gibi gelmeyen tek cevaptır, ancak referans alınan blog gönderisindeki orijinal örnek daha doğrudur çünkü kök düğümdeki ad alanını kaldırmazsanız, tüm alt düğümler ve öznitelikler ad alanı, kök ad alanını miras alır.
tenor

8

Bu, Peter Stegnar'ın kabul ettiği cevaba dayanan bir çözüm.

Onu kullandım, ancak (andygjp ve John Saunders'ın belirttiği gibi) kodu nitelikleri görmezden geliyor .

Özelliklere de dikkat etmem gerekiyordu, bu yüzden kodunu uyarladım. Andy'nin sürümü Visual Basic idi, bu hala c #.

Biliyorum uzun zaman oldu, ama belki bir gün birini kurtarır.

    private static XElement RemoveAllNamespaces(XElement xmlDocument)
    {
        XElement xmlDocumentWithoutNs = removeAllNamespaces(xmlDocument);
        return xmlDocumentWithoutNs;
    }

    private static XElement removeAllNamespaces(XElement xmlDocument)
    {
        var stripped = new XElement(xmlDocument.Name.LocalName);            
        foreach (var attribute in
                xmlDocument.Attributes().Where(
                attribute =>
                    !attribute.IsNamespaceDeclaration &&
                    String.IsNullOrEmpty(attribute.Name.NamespaceName)))
        {
            stripped.Add(new XAttribute(attribute.Name.LocalName, attribute.Value));
        }
        if (!xmlDocument.HasElements)
        {
            stripped.Value = xmlDocument.Value;
            return stripped;
        }
        stripped.Add(xmlDocument.Elements().Select(
            el =>
                RemoveAllNamespaces(el)));            
        return stripped;
    }

6

Dexter'ın nereye gittiğini gerçekten çok beğendim , bu yüzden onu "akıcı" bir genişletme yöntemine çevirdim:

/// <summary>
/// Returns the specified <see cref="XElement"/>
/// without namespace qualifiers on elements and attributes.
/// </summary>
/// <param name="element">The element</param>
public static XElement WithoutNamespaces(this XElement element)
{
    if (element == null) return null;

    #region delegates:

        Func<XNode, XNode> getChildNode = e => (e.NodeType == XmlNodeType.Element) ? (e as XElement).WithoutNamespaces() : e;

        Func<XElement, IEnumerable<XAttribute>> getAttributes = e => (e.HasAttributes) ?
            e.Attributes()
                .Where(a => !a.IsNamespaceDeclaration)
                .Select(a => new XAttribute(a.Name.LocalName, a.Value))
            :
            Enumerable.Empty<XAttribute>();

        #endregion

    return new XElement(element.Name.LocalName,
        element.Nodes().Select(getChildNode),
        getAttributes(element));
}

"Akıcı" yaklaşım bunu yapmama izin veriyor:

var xml = File.ReadAllText(presentationFile);
var xDoc = XDocument.Parse(xml);
var xRoot = xDoc.Root.WithoutNamespaces();

1
Bu çözüm için teşekkürler! Sorunum için harika çalışıyor.
AngieM

1
Bu idealdi ÇÜNKÜ nitelikler üzerinde çalışıyordu. Bunu sorunsuz bir şekilde kullanabildim. Teşekkürler
julian lepistes

4

Bunu Linq kullanarak yapabilirsiniz:

public static string RemoveAllNamespaces(string xmlDocument)
{
    var xml = XElement.Parse(xmlDocument);
    xml.Descendants().Select(o => o.Name = o.Name.LocalName).ToArray();
    return xml.ToString();
}

3

Peter'ın cevabını biraz değiştirdi, bu özellik için de iyi çalışıyor, ad alanını ve ön eki kaldırmak dahil. Kod için biraz üzgünüm biraz çirkin görünüyor.

 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(new XAttribute(attribute.Name.LocalName, attribute.Value));
                }

                return xElement;
            }

            else
            {
                XElement xElement = new XElement(xmlDocument.Name.LocalName,  xmlDocument.Elements().Select(el => RemoveAllNamespaces(el)));

                foreach (XAttribute attribute in xmlDocument.Attributes())
                {
                    xElement.Add(new XAttribute(attribute.Name.LocalName, attribute.Value));
                }

                return xElement;
            }

    }

+1 Bu benim için çalıştı. Ancak, ad alanı tanımının parçası olan öznitelikleri bırakır (yalnızca xmlns öneki kaldırılır), ancak şu anda serileştirmeyi etkilemezler.
Rami A.

2

Jimmy ve Peter'ın cevabı çok yardımcı oldu, ancak aslında tüm nitelikleri kaldırdılar, bu yüzden küçük bir değişiklik yaptım:

Imports System.Runtime.CompilerServices

Friend Module XElementExtensions

    <Extension()> _
    Public Function RemoveAllNamespaces(ByVal element As XElement) As XElement
        If element.HasElements Then
            Dim cleanElement = RemoveAllNamespaces(New XElement(element.Name.LocalName, element.Attributes))
            cleanElement.Add(element.Elements.Select(Function(el) RemoveAllNamespaces(el)))
            Return cleanElement
        Else
            Dim allAttributesExceptNamespaces = element.Attributes.Where(Function(attr) Not attr.IsNamespaceDeclaration)
            element.ReplaceAttributes(allAttributesExceptNamespaces)
            Return element
        End If

    End Function

End Module

2

Bu partiye biraz geç ama işte son zamanlarda kullandığım şey:

var doc = XDocument.Parse(xmlString);
doc.Root.DescendantNodesAndSelf().OfType<XElement>().Attributes().Where(att => att.IsNamespaceDeclaration).Remove();

(bu MSDN İş Parçacığından alınmıştır )

Düzenle Aşağıdaki yoruma göre, bu, ad alanı önekini düğümlerden kaldırırken aslında xmlns niteliğini kaldırmadığı görülmektedir. Bunu yapmak için her bir düğümün adını kendi yerel adına sıfırlamanız gerekir (örneğin ad eksi ad alanı)

foreach (var node in doc.Root.DescendantNodesAndSelf().OfType<XElement>())
{
    node.Name = node.Name.LocalName;
}

İşe yaramıyor gibi görünüyor? Tüm ad alanı bildirimlerini bulur, ancak bu koleksiyonda Remove () 'u çağırmak hiçbir şey yapmaz. Result.ToString () denedim ve sonuçta elde edilen dizge hala xmlns özniteliğine sahip. Yanlış bir şey mi yapıyorum?
Jimmy

O zaman ihtiyacım olan şey için çalıştı ama şimdi geriye dönüp baktığımda% 100 değil. Ad alanı öneklerini düğümlerden kaldırıyor (ihtiyacım olan buydu) ama xmlns niteliğini geride bırakma konusunda haklısınız. Garip bir şekilde, bu öznitelik de XDocument yöntemlerinden hiçbiri tarafından tanınmıyor!
MarcE

1

Özniteliklerin çalışması için öznitelik eklemek için for döngüsünün özyinelemeden sonra gitmesi gerekir, ayrıca IsNamespaceDeclaration olup olmadığını kontrol etmeniz gerekir:

private static XElement RemoveAllNamespaces(XElement xmlDocument)
{
    XElement xElement;

    if (!xmlDocument.HasElements)
    {
        xElement = new XElement(xmlDocument.Name.LocalName) { Value = xmlDocument.Value };
    }
    else
    {
        xElement = new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(RemoveAllNamespaces));
    }

    foreach (var attribute in xmlDocument.Attributes())
    {
        if (!attribute.IsNamespaceDeclaration)
        {
            xElement.Add(attribute);
        }
    }

    return xElement;
}

1

İşte Dexter Legaspi C # Sürümünün VB.NET sürümü

Shared Function RemoveAllNamespaces(ByVal e As XElement) As XElement
        Return New XElement(e.Name.LocalName, New Object() {(From n In e.Nodes Select If(TypeOf n Is XElement, RemoveAllNamespaces(TryCast(n, XElement)), n)), If(e.HasAttributes, (From a In e.Attributes Select a), Nothing)})
End Function

1

Muhtemelen araya giren TEXT ve ELEMENT düğümlerini hesaba katan başka bir çözüm, örneğin:

<parent>
    text1
    <child1/>
    text2
    <child2/>
</parent>

Kod:

using System.Linq;

namespace System.Xml.Linq
{
    public static class XElementTransformExtensions
    {
        public static XElement WithoutNamespaces(this XElement source)
        {
            return new XElement(source.Name.LocalName,
                source.Attributes().Select(WithoutNamespaces),
                source.Nodes().Select(WithoutNamespaces)
            );
        }

        public static XAttribute WithoutNamespaces(this XAttribute source)
        {
            return !source.IsNamespaceDeclaration
                ? new XAttribute(source.Name.LocalName, source.Value)
                : default(XAttribute);
        }

        public static XNode WithoutNamespaces(this XNode source)
        {
            return
                source is XElement
                    ? WithoutNamespaces((XElement)source)
                    : source;
        }
    }
}

1

XSLT tabanlı bir çözüme başvurmadan, temiz, zarif ve akıllı istiyorsanız, çerçeveden biraz desteğe ihtiyacınız olacak, özellikle ziyaretçi düzeni bunu çocuk oyuncağı haline getirebilir. Maalesef burada mevcut değil.

ExpressionVisitorBenzer bir yapıya sahip olması için LINQ'lardan ilham alarak uyguladım . Bununla, ziyaretçi desenini (LINQ-to-) XML nesnelerine uygulayabilirsiniz. (Bu konuda sınırlı testler yaptım ama anlayabildiğim kadarıyla iyi çalışıyor)

public abstract class XObjectVisitor
{
    public virtual XObject Visit(XObject node)
    {
        if (node != null)
            return node.Accept(this);
        return node;
    }

    public ReadOnlyCollection<XObject> Visit(IEnumerable<XObject> nodes)
    {
        return nodes.Select(node => Visit(node))
            .Where(node => node != null)
            .ToList()
            .AsReadOnly();
    }

    public T VisitAndConvert<T>(T node) where T : XObject
    {
        if (node != null)
            return Visit(node) as T;
        return node;
    }

    public ReadOnlyCollection<T> VisitAndConvert<T>(IEnumerable<T> nodes) where T : XObject
    {
        return nodes.Select(node => VisitAndConvert(node))
            .Where(node => node != null)
            .ToList()
            .AsReadOnly();
    }

    protected virtual XObject VisitAttribute(XAttribute node)
    {
        return node.Update(node.Name, node.Value);
    }

    protected virtual XObject VisitComment(XComment node)
    {
        return node.Update(node.Value);
    }

    protected virtual XObject VisitDocument(XDocument node)
    {
        return node.Update(
            node.Declaration,
            VisitAndConvert(node.Nodes())
        );
    }

    protected virtual XObject VisitElement(XElement node)
    {
        return node.Update(
            node.Name,
            VisitAndConvert(node.Attributes()),
            VisitAndConvert(node.Nodes())
        );
    }

    protected virtual XObject VisitDocumentType(XDocumentType node)
    {
        return node.Update(
            node.Name,
            node.PublicId,
            node.SystemId,
            node.InternalSubset
        );
    }

    protected virtual XObject VisitProcessingInstruction(XProcessingInstruction node)
    {
        return node.Update(
            node.Target,
            node.Data
        );
    }

    protected virtual XObject VisitText(XText node)
    {
        return node.Update(node.Value);
    }

    protected virtual XObject VisitCData(XCData node)
    {
        return node.Update(node.Value);
    }

    #region Implementation details
    internal InternalAccessor Accessor
    {
        get { return new InternalAccessor(this); }
    }

    internal class InternalAccessor
    {
        private XObjectVisitor visitor;
        internal InternalAccessor(XObjectVisitor visitor) { this.visitor = visitor; }

        internal XObject VisitAttribute(XAttribute node) { return visitor.VisitAttribute(node); }
        internal XObject VisitComment(XComment node) { return visitor.VisitComment(node); }
        internal XObject VisitDocument(XDocument node) { return visitor.VisitDocument(node); }
        internal XObject VisitElement(XElement node) { return visitor.VisitElement(node); }
        internal XObject VisitDocumentType(XDocumentType node) { return visitor.VisitDocumentType(node); }
        internal XObject VisitProcessingInstruction(XProcessingInstruction node) { return visitor.VisitProcessingInstruction(node); }
        internal XObject VisitText(XText node) { return visitor.VisitText(node); }
        internal XObject VisitCData(XCData node) { return visitor.VisitCData(node); }
    }
    #endregion
}

public static class XObjectVisitorExtensions
{
    #region XObject.Accept "instance" method
    public static XObject Accept(this XObject node, XObjectVisitor visitor)
    {
        Validation.CheckNullReference(node);
        Validation.CheckArgumentNull(visitor, "visitor");

        // yay, easy dynamic dispatch
        Acceptor acceptor = new Acceptor(node as dynamic);
        return acceptor.Accept(visitor);
    }
    private class Acceptor
    {
        public Acceptor(XAttribute node) : this(v => v.Accessor.VisitAttribute(node)) { }
        public Acceptor(XComment node) : this(v => v.Accessor.VisitComment(node)) { }
        public Acceptor(XDocument node) : this(v => v.Accessor.VisitDocument(node)) { }
        public Acceptor(XElement node) : this(v => v.Accessor.VisitElement(node)) { }
        public Acceptor(XDocumentType node) : this(v => v.Accessor.VisitDocumentType(node)) { }
        public Acceptor(XProcessingInstruction node) : this(v => v.Accessor.VisitProcessingInstruction(node)) { }
        public Acceptor(XText node) : this(v => v.Accessor.VisitText(node)) { }
        public Acceptor(XCData node) : this(v => v.Accessor.VisitCData(node)) { }

        private Func<XObjectVisitor, XObject> accept;
        private Acceptor(Func<XObjectVisitor, XObject> accept) { this.accept = accept; }

        public XObject Accept(XObjectVisitor visitor) { return accept(visitor); }
    }
    #endregion

    #region XObject.Update "instance" method
    public static XObject Update(this XAttribute node, XName name, string value)
    {
        Validation.CheckNullReference(node);
        Validation.CheckArgumentNull(name, "name");
        Validation.CheckArgumentNull(value, "value");

        return new XAttribute(name, value);
    }
    public static XObject Update(this XComment node, string value = null)
    {
        Validation.CheckNullReference(node);

        return new XComment(value);
    }
    public static XObject Update(this XDocument node, XDeclaration declaration = null, params object[] content)
    {
        Validation.CheckNullReference(node);

        return new XDocument(declaration, content);
    }
    public static XObject Update(this XElement node, XName name, params object[] content)
    {
        Validation.CheckNullReference(node);
        Validation.CheckArgumentNull(name, "name");

        return new XElement(name, content);
    }
    public static XObject Update(this XDocumentType node, string name, string publicId = null, string systemId = null, string internalSubset = null)
    {
        Validation.CheckNullReference(node);
        Validation.CheckArgumentNull(name, "name");

        return new XDocumentType(name, publicId, systemId, internalSubset);
    }
    public static XObject Update(this XProcessingInstruction node, string target, string data)
    {
        Validation.CheckNullReference(node);
        Validation.CheckArgumentNull(target, "target");
        Validation.CheckArgumentNull(data, "data");

        return new XProcessingInstruction(target, data);
    }
    public static XObject Update(this XText node, string value = null)
    {
        Validation.CheckNullReference(node);

        return new XText(value);
    }
    public static XObject Update(this XCData node, string value = null)
    {
        Validation.CheckNullReference(node);

        return new XCData(value);
    }
    #endregion
}

public static class Validation
{
    public static void CheckNullReference<T>(T obj) where T : class
    {
        if (obj == null)
            throw new NullReferenceException();
    }

    public static void CheckArgumentNull<T>(T obj, string paramName) where T : class
    {
        if (obj == null)
            throw new ArgumentNullException(paramName);
    }
}

ps, bu özel uygulama, uygulamayı biraz daha kolay / daha temiz hale getirmek için ( dynamicve varsayılan argümanların kullanımı ) bazı .NET 4 özelliklerini kullanır . .NET 3.5 uyumlu, hatta .NET 2.0 uyumlu hale getirmek çok zor olmamalıdır.

Ardından ziyaretçiyi uygulamak için, burada birden çok ad alanını (ve kullanılan öneki) değiştirebilen genelleştirilmiş bir tane var.

public class ChangeNamespaceVisitor : XObjectVisitor
{
    private INamespaceMappingManager manager;
    public ChangeNamespaceVisitor(INamespaceMappingManager manager)
    {
        Validation.CheckArgumentNull(manager, "manager");

        this.manager = manager;
    }

    protected INamespaceMappingManager Manager { get { return manager; } }

    private XName ChangeNamespace(XName name)
    {
        var mapping = Manager.GetMapping(name.Namespace);
        return mapping.ChangeNamespace(name);
    }

    private XObject ChangeNamespaceDeclaration(XAttribute node)
    {
        var mapping = Manager.GetMapping(node.Value);
        return mapping.ChangeNamespaceDeclaration(node);
    }

    protected override XObject VisitAttribute(XAttribute node)
    {
        if (node.IsNamespaceDeclaration)
            return ChangeNamespaceDeclaration(node);
        return node.Update(ChangeNamespace(node.Name), node.Value);
    }

    protected override XObject VisitElement(XElement node)
    {
        return node.Update(
            ChangeNamespace(node.Name),
            VisitAndConvert(node.Attributes()),
            VisitAndConvert(node.Nodes())
        );
    }
}

// and all the gory implementation details
public class NamespaceMappingManager : INamespaceMappingManager
{
    private Dictionary<XNamespace, INamespaceMapping> namespaces = new Dictionary<XNamespace, INamespaceMapping>();

    public NamespaceMappingManager Add(XNamespace fromNs, XNamespace toNs, string toPrefix = null)
    {
        var item = new NamespaceMapping(fromNs, toNs, toPrefix);
        namespaces.Add(item.FromNs, item);
        return this;
    }

    public INamespaceMapping GetMapping(XNamespace fromNs)
    {
        INamespaceMapping mapping;
        if (!namespaces.TryGetValue(fromNs, out mapping))
            mapping = new NullMapping();
        return mapping;
    }

    private class NullMapping : INamespaceMapping
    {
        public XName ChangeNamespace(XName name)
        {
            return name;
        }

        public XObject ChangeNamespaceDeclaration(XAttribute node)
        {
            return node.Update(node.Name, node.Value);
        }
    }

    private class NamespaceMapping : INamespaceMapping
    {
        private XNamespace fromNs;
        private XNamespace toNs;
        private string toPrefix;
        public NamespaceMapping(XNamespace fromNs, XNamespace toNs, string toPrefix = null)
        {
            this.fromNs = fromNs ?? "";
            this.toNs = toNs ?? "";
            this.toPrefix = toPrefix;
        }

        public XNamespace FromNs { get { return fromNs; } }
        public XNamespace ToNs { get { return toNs; } }
        public string ToPrefix { get { return toPrefix; } }

        public XName ChangeNamespace(XName name)
        {
            return name.Namespace == fromNs
                ? toNs + name.LocalName
                : name;
        }

        public XObject ChangeNamespaceDeclaration(XAttribute node)
        {
            if (node.Value == fromNs.NamespaceName)
            {
                if (toNs == XNamespace.None)
                    return null;
                var xmlns = !String.IsNullOrWhiteSpace(toPrefix)
                    ? (XNamespace.Xmlns + toPrefix)
                    : node.Name;
                return node.Update(xmlns, toNs.NamespaceName);
            }
            return node.Update(node.Name, node.Value);
        }
    }
}

public interface INamespaceMappingManager
{
    INamespaceMapping GetMapping(XNamespace fromNs);
}

public interface INamespaceMapping
{
    XName ChangeNamespace(XName name);
    XObject ChangeNamespaceDeclaration(XAttribute node);
}

Ve topu yuvarlamak için küçük bir yardımcı yöntem:

T ChangeNamespace<T>(T node, XNamespace fromNs, XNamespace toNs, string toPrefix = null) where T : XObject
{
    return node.Accept(
        new ChangeNamespaceVisitor(
            new NamespaceMappingManager()
                .Add(fromNs, toNs, toPrefix)
        )
    ) as T;
}

Ardından bir ad alanını kaldırmak için şu şekilde adlandırabilirsiniz:

var doc = ChangeNamespace(XDocument.Load(pathToXml),
    fromNs: "http://schema.peters.com/doc_353/1/Types",
    toNs: null);

Bu ziyaretçiyi kullanarak, INamespaceMappingManagertüm ad alanlarını kaldırmak için bir yazabilirsiniz .

T RemoveAllNamespaces<T>(T node) where T : XObject
{
    return node.Accept(
        new ChangeNamespaceVisitor(new RemoveNamespaceMappingManager())
    ) as T;
}

public class RemoveNamespaceMappingManager : INamespaceMappingManager
{
    public INamespaceMapping GetMapping(XNamespace fromNs)
    {
        return new RemoveNamespaceMapping();
    }

    private class RemoveNamespaceMapping : INamespaceMapping
    {
        public XName ChangeNamespace(XName name)
        {
            return name.LocalName;
        }

        public XObject ChangeNamespaceDeclaration(XAttribute node)
        {
            return null;
        }
    }
}

1

Öğeleri yerinde yeniden adlandıran, bir kopya oluşturmayan ve öznitelikleri değiştirmek için oldukça iyi bir iş çıkaran basit bir çözüm.

public void RemoveAllNamespaces(ref XElement value)
{
  List<XAttribute> attributesToRemove = new List<XAttribute>();
  foreach (void e_loopVariable in value.DescendantsAndSelf) {
    e = e_loopVariable;
    if (e.Name.Namespace != XNamespace.None) {
      e.Name = e.Name.LocalName;
    }
    foreach (void a_loopVariable in e.Attributes) {
      a = a_loopVariable;
      if (a.IsNamespaceDeclaration) {
        //do not keep it at all
        attributesToRemove.Add(a);
      } else if (a.Name.Namespace != XNamespace.None) {
        e.SetAttributeValue(a.Name.LocalName, a.Value);
        attributesToRemove.Add(a);
      }
    }
  }
  foreach (void a_loopVariable in attributesToRemove) {
    a = a_loopVariable;
    a.Remove();
  }
}

Not: Bu her zaman orijinal öznitelik sırasını korumaz, ancak sizin için önemliyse bunu oldukça kolay bir şekilde yapmak için değiştirebileceğinizden eminim.

Ayrıca, bu da unutmayın olabilir Eğer ad gibi sadece benzersiz bir XElement özelliklerini olsaydı, bir istisna:

<root xmlns:ns1="a" xmlns:ns2="b">
    <elem ns1:dupAttrib="" ns2:dupAttrib="" />
</root>

bu gerçekten içsel bir sorun gibi görünüyor. Ancak soru, bir XElement değil, bir String çıktılamayı gösterdiğinden, bu durumda, geçersiz bir XElement olan geçerli bir String çıkaran bir çözüme sahip olabilirsiniz.

Ayrıca özel bir XmlWriter kullanarak jocull'un cevabını beğendim, ancak denediğimde benim için işe yaramadı. Hepsi rağmen görünüyor doğru XmlNoNamespaceWriter sınıfı hiç bir etkisi olsaydı, ben anlayamadı; kesinlikle istediğim gibi ad alanlarını kaldırmıyordu.


1

Bunu eklemek, ad alanı öneklerine sahip düğümlerin adlarını da temizler:

    public static string RemoveAllNamespaces(XElement element)
    {
        string tex = element.ToString();
        var nsitems = element.DescendantsAndSelf().Select(n => n.ToString().Split(' ', '>')[0].Split('<')[1]).Where(n => n.Contains(":")).DistinctBy(n => n).ToArray();

        //Namespace prefix on nodes: <a:nodename/>
        tex = nsitems.Aggregate(tex, (current, nsnode) => current.Replace("<"+nsnode + "", "<" + nsnode.Split(':')[1] + ""));
        tex = nsitems.Aggregate(tex, (current, nsnode) => current.Replace("</" + nsnode + "", "</" + nsnode.Split(':')[1] + ""));

        //Namespace attribs
        var items = element.DescendantsAndSelf().SelectMany(d => d.Attributes().Where(a => a.IsNamespaceDeclaration || a.ToString().Contains(":"))).DistinctBy(o => o.Value);
        tex = items.Aggregate(tex, (current, xAttribute) => current.Replace(xAttribute.ToString(), ""));

        return tex;
    }

1

İlk birkaç çözümü denedim ve benim için işe yaramadı. Esasen, daha önce de belirtildiği gibi kaldırılan özniteliklerle ilgili sorun. Yaklaşımımın nesneyi parametre olarak alan XElement kurucularını kullanarak Jimmy'ye çok benzediğini söyleyebilirim.

public static XElement RemoveAllNamespaces(this XElement element)
{
    return new XElement(element.Name.LocalName,
                        element.HasAttributes ? element.Attributes().Select(a => new XAttribute(a.Name.LocalName, a.Value)) : null,
                        element.HasElements ? element.Elements().Select(e => RemoveAllNamespaces(e)) : null,
                        element.Value);
}

1

cevabım, dize işleme tabanlı,
en basit kod,

public static string hilangkanNamespace(string instrXML)
    {
        char chrOpeningTag = '<';
        char chrClosingTag = '>';
        char chrSpasi = ' ';
        int intStartIndex = 0;
        do
        {
            int intIndexKu = instrXML.IndexOf(chrOpeningTag, intStartIndex);
            if (intIndexKu < 0)
                break; //kalau dah ga ketemu keluar
            int intStart = instrXML.IndexOfAny(new char[] { chrSpasi, chrClosingTag }, intIndexKu + 1); //mana yang ketemu duluan
            if (intStart < 0)
                break; //kalau dah ga ketemu keluar
            int intStop = instrXML.IndexOf(chrClosingTag, intStart);
            if (intStop < 0)
                break; //kalau dah ga ketemu keluar
            else
                intStop--; //exclude si closingTag
            int intLengthToStrip = intStop - intStart + 1;
            instrXML = instrXML.Remove(intStart, intLengthToStrip);
            intStartIndex = intStart;
        } while (true);

        return instrXML;
    }

1

İşte Regex Bir satır değiştirin:

public static string RemoveNamespaces(this string xml)
{
    return Regex.Replace(xml, "((?<=<|<\\/)|(?<= ))[A-Za-z0-9]+:| xmlns(:[A-Za-z0-9]+)?=\".*?\"", "");
}

İşte bir örnek: https://regex101.com/r/fopydN/6

Uyarı: Uç durumlar olabilir!


0

user892217'nin yanıtı neredeyse doğrudur. Olduğu gibi derlenmez, bu nedenle özyinelemeli çağrı için küçük bir düzeltme yapılması gerekir:

private static XElement RemoveAllNamespaces(XElement xmlDocument)
{
    XElement xElement;

    if (!xmlDocument.HasElements)
    {
        xElement = new XElement(xmlDocument.Name.LocalName) { Value = xmlDocument.Value };
    }
    else
    {
        xElement = new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(x => RemoveAllNamespaces(x)));
    }

    foreach (var attribute in xmlDocument.Attributes())
    {
        if (!attribute.IsNamespaceDeclaration)
        {
            xElement.Add(attribute);
        }
    }

    return xElement;
}

0

Bu benim için çalıştı.

       FileStream fs = new FileStream(filePath, FileMode.Open);

       StreamReader sr = new StreamReader(fs);

        DataSet ds = new DataSet();
        ds.ReadXml(sr);
        ds.Namespace = "";

        string outXML = ds.GetXml();
        ds.Dispose();
        sr.Dispose();
        fs.Dispose();

0

Bu konuya çok fazla çözüm aradıktan sonra, bu özel sayfada en fazla ete sahip gibi görünüyordu ... ancak, hiçbir şey tam olarak uymuyordu, bu yüzden eski moda yolu seçtim ve sadece istediğim şeyleri ayrıştırdım. Umarım bu birine yardımcı olur. (Not: Bu aynı zamanda SABUN veya benzeri zarf malzemelerini de kaldırır.)

        public static string RemoveNamespaces(string psXml)
    {
        //
        // parse through the passed XML, and remove any and all namespace references...also
        // removes soap envelope/header(s)/body, or any other references via ":" entities,
        // leaving all data intact
        //
        string xsXml = "", xsCurrQtChr = "";
        int xiPos = 0, xiLastPos = psXml.Length - 1;
        bool xbInNode = false;

        while (xiPos <= xiLastPos)
        {
            string xsCurrChr = psXml.Substring(xiPos, 1);
            xiPos++;
            if (xbInNode)
            {
                if (xsCurrChr == ":")
                {
                    // soap envelope or body (or some such)
                    // we'll strip these node wrappers completely
                    // need to first strip the beginning of it off  (i.e. "<soap" or "<s")
                    int xi = xsXml.Length;
                    string xsChr = "";
                    do
                    {
                        xi--;
                        xsChr = xsXml.Substring(xi, 1);
                        xsXml = xsXml.Substring(0, xi);
                    } while (xsChr != "<");

                    // next, find end of node
                    string xsQt = "";
                    do
                    {
                        xiPos++;
                        if (xiPos <= xiLastPos)
                        {
                            xsChr = psXml.Substring(xiPos, 1);
                            if (xsQt.Length == 0)
                            {
                                if (xsChr == "'" || xsChr == "\"")
                                {
                                    xsQt = xsChr;
                                }
                            }
                            else
                            {
                                if (xsChr == xsQt)
                                {
                                    xsQt = "";  // end of quote
                                }
                                else
                                {
                                    if (xsChr == ">") xsChr = "x";      // stay in loop...this is not end of node
                                }
                            }
                        }
                    } while (xsChr != ">" && xiPos <= xiLastPos);
                    xiPos++;            // skip over closing ">"
                    xbInNode = false;
                }
                else
                {
                    if (xsCurrChr == ">")
                    {
                        xbInNode = false;
                        xsXml += xsCurrChr;
                    }
                    else
                    {
                        if (xsCurrChr == " " || xsCurrChr == "\t")
                        {
                            // potential namespace...let's check...next character must be "/"
                            // or more white space, and if not, skip until we find such
                            string xsChr = "";
                            int xiOrgLen = xsXml.Length;
                            xsXml += xsCurrChr;
                            do
                            {
                                if (xiPos <= xiLastPos)
                                {
                                    xsChr = psXml.Substring(xiPos, 1);
                                    xiPos++;
                                    if (xsChr == " " || xsChr == "\r" || xsChr == "\n" || xsChr == "\t")
                                    {
                                        // carry on..white space
                                        xsXml += xsChr;
                                    }
                                    else
                                    {
                                        if (xsChr == "/" || xsChr == ">")
                                        {
                                            xsXml += xsChr;
                                        }
                                        else
                                        {
                                            // namespace! - get rid of it
                                            xsXml = xsXml.Substring(0, xiOrgLen - 0);       // first, truncate any added whitespace
                                            // next, peek forward until we find "/" or ">"
                                            string xsQt = "";
                                            do
                                            {
                                                if (xiPos <= xiLastPos)
                                                {
                                                    xsChr = psXml.Substring(xiPos, 1);
                                                    xiPos++;
                                                    if (xsQt.Length > 0)
                                                    {
                                                        if (xsChr == xsQt) xsQt = ""; else xsChr = "x";
                                                    }
                                                    else
                                                    {
                                                        if (xsChr == "'" || xsChr == "\"") xsQt = xsChr;
                                                    }
                                                }
                                            } while (xsChr != ">" && xsChr != "/" && xiPos <= xiLastPos);
                                            if (xsChr == ">" || xsChr == "/") xsXml += xsChr;
                                            xbInNode = false;
                                        }
                                    }
                                }
                            } while (xsChr != ">" && xsChr != "/" && xiPos <= xiLastPos);
                        }
                        else
                        {
                            xsXml += xsCurrChr;
                        }
                    }
                }
            }
            else
            {
                //
                // if not currently inside a node, then we are in a value (or about to enter a new node)
                //
                xsXml += xsCurrChr;
                if (xsCurrQtChr.Length == 0)
                {
                    if (xsCurrChr == "<")
                    {
                        xbInNode = true;
                    }
                }
                else
                {
                    //
                    // currently inside a quoted string
                    //
                    if (xsCurrQtChr == xsCurrChr)
                    {
                        // finishing quoted string
                        xsCurrQtChr = "";
                    }
                }
            }
        }

        return (xsXml);
    }

0

Tüm düğüm hiyerarşisini yeniden oluşturmadan:

private static void RemoveDefNamespace(XElement element)
{
    var defNamespase = element.Attribute("xmlns");
    if (defNamespase != null)
        defNamespase.Remove();

    element.Name = element.Name.LocalName;
    foreach (var child in element.Elements())
    {
        RemoveDefNamespace(child);
    }
}

0

Çözümlerden bazılarını denedim, ancak pek çok kişinin belirttiği gibi, bazı uç durumlar var.

Yukarıdaki normal ifadelerden bazılarını kullandık, ancak tek adımlı bir normal ifadenin uygulanabilir olmadığı sonucuna varıldı.

İşte benim çözümüm, 2 adımlı regex, etiketleri bul, etiketlerin içinde kaldır, cdata'yı değiştirme:

            Func<Match, String> NamespaceRemover = delegate (Match match)
            {
                var result = match.Value;
                if (String.IsNullOrEmpty(match.Groups["cdata"].Value))
                {
                    // find all prefixes within start-, end tag and attributes and also namespace declarations
                    return Regex.Replace(result, "((?<=<|<\\/| ))\\w+:| xmlns(:\\w+)?=\".*?\"", "");
                }
                else
                {
                    // cdata as is
                    return result;
                }
            };
            // XmlDocument doc;
            // string file;
            doc.LoadXml(
              Regex.Replace(File.ReadAllText(file), 
                // find all begin, cdata and end tags (do not change order)
                @"<(?:\w+:?\w+.*?|(?<cdata>!\[CDATA\[.*?\]\])|\/\w+:?\w+)>", 
                new MatchEvaluator(NamespaceRemover)
              )
            );

Şimdilik% 100 benim için çalışıyor.


-1

İşte bu soruna normal ifadeye dayalı bir çözüm ...

    private XmlDocument RemoveNS(XmlDocument doc)
    {
        var xml = doc.OuterXml;
        var newxml = Regex.Replace(xml, @"xmlns[:xsi|:xsd]*="".*?""","");
        var newdoc = new XmlDocument();
        newdoc.LoadXml(newxml);
        return newdoc;
    }

-1

Bunun en kısa cevap olduğunu düşünüyorum (ancak, başka bir tartışma için başka bir tartışmanız olacak, ayrıca "<bcm:info></bcm:info>"" <info></info>" olarak dönüştürmem gereken normal ifadem var, ancak optimize edilmedi, biri sorarsa onu paylaşacağım. Yani benim çözümüm:

    public string RemoveAllNamespaces(string xmlDocument)
    {
        return Regex.Replace(xmlDocument, @"\sxmlns(\u003A\w+)?\u003D\u0022.+\u0022", " ");
    }
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.