替换字符串(XML格式)中的某些字符

本文关键字:字符 字符串 XML 格式 替换 | 更新日期: 2023-09-27 18:11:27

我得到了一个字符串变量,内容如下:

<main>
<Title title="Hello World" />
<Content content="bla bla bla... by <1% to ??? on other bla bla...." />
</main>

这个字符串最终将传递给XQuery的存储过程。

可以看到," content "的内容包含char "<</strong>,当我试图在存储过程中解析它时,它返回一个错误。

我的问题是如何转换"<" , lt; (在这种情况下 & lt; 1% , , lt; 1% )在一个有效的方式。

我想保留其他"<</strong>

谢谢

替换字符串(XML格式)中的某些字符

既然您更新了您的问题以指出您正在处理XML,但未编码的值在属性值中,而不是#text节点,那么它使它变得更简单,只需使用与我之前的答案类似的方法提取属性值,然后使用库函数将其实体化,然后输出。

注意CDATA只适用于#text,而不适用于属性。

String doc =
@"<main>
<Title title=""Hello World"" />
<Content content=""bla bla bla... by <1% to ??? on other bla bla...."" />
</main>";
Int32 contentOpenStart = doc.IndexOf("<Content");
Int32 contentAttribContentValueStart = doc.IndexOf("content='"", contentOpenStart) + "content='"".Length;
Int32 contentAttibContentValueEnd    = doc.IndexOf("'"", contentAttribContentValueStart);
String attributeValueOld = doc.Substring( contentAttribContentValueStart, contentAttibContentValueEnd );
String attributeValueNew = System.Net.WebUtility.HtmlEncode( attributeValueOld );
String doc2 = String.Concat(
    doc.Substring( 0, contentAttribContentValueStart );
    attributeValueNew,
    doc.Substring( contentAttibContentValueEnd );
);

doc2则包含固定属性值。

请注意,使用HtmlEncode来执行实体的HTML编码在XML中并不是严格正确的,因为XML实体的集合比HTML的小得多-实际上,XML只关心&amp;, &gt;, &lt;, &quot;&apos;,所有其他值都应该在文档中作为原始/本地字符。

(此答案基于您正在处理结构正确的XML的假设,仅使用#text节点中未编码的实体—如果您的输入数据确实看起来像<Title="foo" />—这根本不是XML,则此答案不适用)

如果我正确理解你的问题,你在String实例中有一个XML文档,其中包含不正确转义/实体化的特殊字符,这使你无法使用正常的XML解析器读取文档。

如果您正在处理一个符合xml的系统,那么您可以使用<![DATA[,然后不需要尝试处理<Content>元素的内容,然后技巧变成插入CDATA分隔符。

虽然人们经常说不能使用正则表达式来解析XML(因为XML不是一种正则语言),但是您可以利用XML的语法规则来提取和识别标记。

所以如果你有这个:

<Content someAttribute="someValue">
reduce sales by <1% in order to ensure that profit > loss
</Content>

然后你可以这样做:

String doc = @"<main><Title...";
Int32 contentOpenStart = doc.IndexOf("<Content");
Int32 contentOpenEnd   = doc.IndexOf(">", contentOpenStart);
Int32 contentCloseStart = doc.IndexOf("</Content>", contentOpenEnd);
这段代码告诉我们<Content>元素的两个标签的尖括号的位置,我们可以用它插入CDATA分隔符:
String newDocument = String.Concat(
    doc.Substring( 0, contentOpenEnd + 1 ), // "<main>...<Content...>"
    "<![CDATA[",
    doc.Substring( contentOpenEnd + 1, contentCloseStart ),
    "]]>",
    doc.Substring( contentCloseStart ) "</Content>..."
);

newDocument则为:

<Content someAttribute="someValue"><![CDATA[
reduce sales by <1% in order to ensure that profit > loss
]]></Content>