简体   繁体   English

将CDATA节点转换为.Net中的编码字符串

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

TL;DR - in.Net and XmlDocument/XDocument is there an easy way (XPath?) to find CDATA nodes, so they can be removed and the contents encoded? TL;DR - in.Net 和 XmlDocument/XDocument 是否有一种简单的方法(XPath?)来查找CDATA节点,以便可以删除它们并对内容进行编码?

Details ...详情...

My system has lots of situations where it builds XML strings manually (eg string concatination, rather than building via XmlDocument or XDocument) which could contain multiple <.[CDATA[...]]> nodes (which could appear at any level of the structure)... eg我的系统在很多情况下会手动构建 XML 个字符串(例如字符串连接,而不是通过 XmlDocument 或 XDocument 构建),其中可能包含多个<.[CDATA[...]]>节点(可能出现在结构)...例如

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

When storing this data in a SQLServer XML column, the <.[CDATA[..]]> is automatically removed and the inner text encoded... this is standard for SQLServer which doesn't "do" CDATA .将此数据存储在 SQLServer XML 列中时, <.[CDATA[..]]>会自动删除并对内部文本进行编码......这是不“执行” CDATA的 SQLServer 的标准。

My issue is that I have complex code that takes two instances of a class, and audit-trails differences between them... one or more could be a string property containing XML.我的问题是我有复杂的代码,它采用 class 的两个实例,并且审计跟踪它们之间的差异......一个或多个可能是包含 XML 的字符串属性。

This results in a mismatch (and therefore an audit-trail entry) when nothing is actually changing, because the code creates one format of XML and SQLServer returns a different form, eg..当实际上没有任何变化时,这会导致不匹配(因此会导致审计跟踪条目),因为代码创建了一种格式 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>

Is there an easy way in.Net to process the manually generated XML and convert each CDATA node into it's encoded version, so I can compare the string to the one returned by SQLServer? .Net 中是否有一种简单的方法来处理手动生成的 XML 并将每个CDATA节点转换为其编码版本,以便我可以将字符串与 SQLServer 返回的字符串进行比较?

Is there a SelectNodes XPath that would find all those elements?是否有SelectNodes XPath 可以找到所有这些元素?

(And before anybody states it, the obvious solution is to not use CDATA in the manual creation of the XML in the first place... however, this is not possible due to the sheer number of instances.) (在任何人声明之前,显而易见的解决方案是首先不在手动创建 XML 时使用CDATA ……但是,由于实例数量过多,这是不可能的。)

Easy with one foreach loop and ReplaceChild :使用一个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);

Outputs产出

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

Another option would be to run the XML through an XSLT identity transformation with XslCompiledTransform and eg另一种选择是使用 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