使用Regex从XML字符串中删除XML节点名称空间前缀

bri*_*and 4 c# regex xml asp.net xmldocument

我有一些遗留的XML文档作为blob存储在数据库中,它们不是格式良好的XML.我正在从SQL数据库中读取它们,最终,当我使用C#.NET时,希望将它们实例化为XMLDocument.

当我尝试这样做时,我显然得到了一个XMLException.看过XML文档之后,由于特定XML节点中未声明的命名空间,它们都失败了.

我并不关心任何具有此前缀的XML节点,因此我可以忽略它们或将它们丢弃.所以基本上,在我将字符串作为XMLDocument加载之前,我想删除字符串中的前缀,以便这样做

<tem:GetRouteID>
        <tem:PostCode>postcode</tem:PostCode>
        <tem:Type>ItemType</tem:Type>
</tem:GetRouteID>
Run Code Online (Sandbox Code Playgroud)

<GetRouteID>
    <PostCode>postcode</PostCode>
    <Type>ItemType</Type>
</GetRouteID>
Run Code Online (Sandbox Code Playgroud)

还有这个

<wsse:Security soapenv:actor="">
    <wsse:BinarySecurityToken>token</wsse:BinarySecurityToken>
</wsse:Security>
Run Code Online (Sandbox Code Playgroud)

成为这个:

<Security soapenv:actor="">
    <BinarySecurityToken>token</BinarySecurityToken>
</Security>
Run Code Online (Sandbox Code Playgroud)

我有一个解决方案,这样做:

<appSettings>
  <add key="STRIP_NAMESPACES" value="wsse;tem" />
</appSettings>
Run Code Online (Sandbox Code Playgroud)
if (STRIP_NAMESPACES != null)
{
    string[] namespaces = Regex.Split(STRIP_NAMESPACES, ";");

    foreach (string ns in namespaces)
   {
        str2 = str2.Replace("<" + ns + ":", "<"); // Replace opening tag
        str2 = str2.Replace("</" + ns + ":", "</"); // Replace closing tag

    }
}
Run Code Online (Sandbox Code Playgroud)

但理想情况下,我想要一个通用的方法,所以我不必无休止地配置我想删除的命名空间.

我怎样才能在C#.NET中实现这一点.我假设一个正则表达式是去这里的方式?

更新1

Ria的正则表达式适用于上述要求.但是,我如何更改正则表达式以更改此值

<wsse:Security soapenv:actor="">
    <BinarySecurityToken>authtoken</BinarySecurityToken>
</Security>
Run Code Online (Sandbox Code Playgroud)

这个?

<Security>
    <BinarySecurityToken>authtoken</BinarySecurityToken>
</Security>
Run Code Online (Sandbox Code Playgroud)

更新2

想想我已经根据Ria的答案自己制定了更新版本,如下所示:

<(/?)\w+:(\w+/?) ?(\w+:\w+.*)?>
Run Code Online (Sandbox Code Playgroud)

Ria*_*Ria 6

UPDATE

对于新问题(attribs命名空间),请尝试这种通用解决方案.这对节点值没有影响:

Regex.Replace(originalXml, 
              @"((?<=</?)\w+:(?<elem>\w+)|\w+:(?<elem>\w+)(?==\"))", 
              "${elem}");
Run Code Online (Sandbox Code Playgroud)

在我的示例xml上试试这个正则表达式:

<wsse:Security soapenv:actor="dont match soapenv:actor attrib">
    <BinarySecurityToken>authtoken</BinarySecurityToken>
</Security> 
Run Code Online (Sandbox Code Playgroud)

尝试使用XSL,您可以XSL直接申请或使用XslTransform.NET中的类:

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

<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>
Run Code Online (Sandbox Code Playgroud)

或试试这个Regex:

var finalXml = Regex.Replace(originalXml, @"<(/?)\w+:(\w+/?)>", "<$1$2>");
Run Code Online (Sandbox Code Playgroud)