簡體   English   中英

將CDATA節點轉換為.Net中的編碼字符串

[英]Convert CDATA node to encoded string in .Net

TL;DR - in.Net 和 XmlDocument/XDocument 是否有一種簡單的方法(XPath?)來查找CDATA節點,以便可以刪除它們並對內容進行編碼?

詳情...

我的系統在很多情況下會手動構建 XML 個字符串(例如字符串連接,而不是通過 XmlDocument 或 XDocument 構建),其中可能包含多個<.[CDATA[...]]>節點(可能出現在結構)...例如

<data><one><![CDATA[ab&cd]]></one><two><inner><![CDATA[xy<z]]></inner></two></data>

將此數據存儲在 SQLServer XML 列中時, <.[CDATA[..]]>會自動刪除並對內部文本進行編碼......這是不“執行” CDATA的 SQLServer 的標准。

我的問題是我有復雜的代碼,它采用 class 的兩個實例,並且審計跟蹤它們之間的差異......一個或多個可能是包含 XML 的字符串屬性。

當實際上沒有任何變化時,這會導致不匹配(因此會導致審計跟蹤條目),因為代碼創建了一種格式 XML 並且 SQLServer 返回不同的格式,例如..

// Manually generated XML string...
<data><one><![CDATA[ab&cd]]></one><two><inner><![CDATA[xy<z]]></inner></two></data>
// SQLServer returned string...
<data><one>ab&amp;cd</one><two><inner>xy&lt;z</inner></two></data>

.Net 中是否有一種簡單的方法來處理手動生成的 XML 並將每個CDATA節點轉換為其編碼版本,以便我可以將字符串與 SQLServer 返回的字符串進行比較?

是否有SelectNodes XPath 可以找到所有這些元素?

(在任何人聲明之前,顯而易見的解決方案是首先不在手動創建 XML 時使用CDATA ……但是,由於實例數量過多,這是不可能的。)

使用一個foreach循環和ReplaceChild很容易:

using System.Xml;

var doc = new XmlDocument();
doc.LoadXml(@"<data><one><![CDATA[ab&cd]]></one><two><inner><![CDATA[xy<z]]></inner></two><three><inner>a &lt; b</inner></three></data>");

foreach (var cdata in doc.SelectNodes("//text()").OfType<XmlCDataSection>())
{
   cdata.ParentNode.ReplaceChild(doc.CreateTextNode(cdata.Data), cdata);
}

Console.WriteLine(doc.OuterXml);

產出

<data><one>ab&amp;cd</one><two><inner>xy&lt;z</inner></two><three><inner>a &lt; b</inner></three></data>

另一種選擇是使用 XslCompiledTransform 通過 XSLT 身份轉換運行 XML,例如

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM