c# - 使用正则表达式从 XML 字符串中删除 XML 节点命名空间前缀

标签 c# asp.net xml regex xmldocument

我有一些旧的 XML 文档作为 blob 存储在数据库中,它们不是格式正确的 XML。我正在从 SQL 数据库中读取它们,最终,因为我使用的是 C#.NET,所以我想将它们实例化为 XMLDocument。

当我尝试这样做时,我显然得到了一个 XMLException。查看 XML 文档后,它们都因特定 XML 节点中未声明的 namespace 而失败。

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

<tem:GetRouteID>
        <tem:PostCode>postcode</tem:PostCode>
        <tem:Type>ItemType</tem:Type>
</tem:GetRouteID>

成为

<GetRouteID>
    <PostCode>postcode</PostCode>
    <Type>ItemType</Type>
</GetRouteID>

还有这个

<wsse:Security soapenv:actor="">
    <wsse:BinarySecurityToken>token</wsse:BinarySecurityToken>
</wsse:Security>

变成这样:

<Security soapenv:actor="">
    <BinarySecurityToken>token</BinarySecurityToken>
</Security>

我有一个这样的解决方案:

<appSettings>
  <add key="STRIP_NAMESPACES" value="wsse;tem" />
</appSettings>
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

    }
}

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

我如何在 C#.NET 中实现这一点。我假设正则表达式是去这里的方式?

更新 1

下面 Ria 的正则表达式可以很好地满足上述要求。但是,我需要如何更改正则表达式才能同时更改此内容

<wsse:Security soapenv:actor="">
    <BinarySecurityToken>authtoken</BinarySecurityToken>
</Security>

为了这个?

<Security>
    <BinarySecurityToken>authtoken</BinarySecurityToken>
</Security>

更新 2

认为我已经根据 Ria 的回答自己制定了更新版本:

<(/?)\w+:(\w+/?) ?(\w+:\w+.*)?>

最佳答案

更新

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

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

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

<wsse:Security soapenv:actor="dont match soapenv:actor attrib">
    <BinarySecurityToken>authtoken</BinarySecurityToken>
</Security> 

尝试使用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>

或者试试这个正则表达式:

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

关于c# - 使用正则表达式从 XML 字符串中删除 XML 节点命名空间前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11737519/

相关文章:

xml - 生成 XML 的 Visual Studio 2012 T4 模板出错

c# - autoeventwireup 的性能成本是多少?

c# - 使用线程时是否需要锁定 "read only"服务?

java - 使用 jaxb 解码 xml 文档的中间部分

xml - XSD:允许序列中任意位置来自不同 namespace 的元素

c# - 使用 C# 从十六进制转换为二进制而不丢失前导 0

c# - 寻找用于即时消息传递的库,例如 libpurple,但用 C# 编写

c# - 如何在条件语句中使用 Linq 的 .Count() 方法

asp.net - iis 将子域重定向到同一子域上的子文件夹

ASP.NET 在不断更新的 Firefox Chrome 中保持滚动位置或回发