2012-07-31 170 views
3

我有一些遺留的XML文檔作爲blob存儲在數據庫中,這些XML文檔格式不正確。我正在從SQL數據庫中讀取它們,並最終在我使用C#.NET時想將它們實例化爲XMLDocument。使用正則表達式從XML字符串中刪除XML節點名稱空間前綴

當我試圖做到這一點,我顯然得到了一個XMLException。查看了XML文檔後,由於特定XML節點中未聲明的名稱空間,它們都失敗了。

我不關心任何具有此前綴的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

下面利雅的正則表達式可以很好地用於上述要求。然而,我將如何改變正則表達式也改變這

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

到這個?

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

更新2

想我已經制定了自己的基於利雅的回答,像這樣的更新版本:

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

我不認爲這是解析XML與正則表達式是個好主意。你可以使用'XDocument','XElement','XmlDocument'(如果你使用.NET 2.0)。 – Leri 2012-07-31 09:58:43

+1

plb - 我不認爲OP正在討論使用正則表達式來解析xml,更多的是通過編輯一些xml節點前綴來使它兼容,以便它可以被讀入xmldoc – 2012-07-31 10:02:45

+0

@jimtollan是的,你是對。我誤解了問題。 – Leri 2012-07-31 10:06:08

回答

4

UPDATE

對於新的問題( 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,您可以直接或使用XslTransform類應用XSL。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> 

或試試這個Regex

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

爲什麼當將XML加載到文檔中時,這不起作用? – svick 2012-07-31 10:19:00

+0

正則表達式是一種享受。非常感謝。 – brianilland 2012-07-31 11:28:43

+0

+1正則表達式看起來像一個很好的通用解決方案 – 2012-07-31 12:00:36

相關問題