本文介绍了字符串转义为XML-Attribute的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看了一下,发现它非常有用。 p>

我想做一个类似的事情:逃避一个要在XML属性中使用的字符串。



字符串可能包含\r\\\

XmlWriter类产生类似\r\\\
- >& #xD;& #xA;



我目前正在使用的解决方案包括XmlWriter和一个StringBuilder,而且很丑陋。



任何提示?



Edit1: / strong>

对不起,LarsH,购买我的第一种方法是

  public static string XmlEscapeAttribute(string unescaped)
{
XmlDocument doc = new XmlDocument();
XmlAttribute attr = doc.CreateAttribute(attr);
attr.InnerText = unescaped;
return attr.InnerXml;
}

它不工作。 XmlEscapeAttribute(Foo\r\\\
Bar)
将导致Foo\r\\\
Bar



我使用.NET Reflector来了解XmlTextWriter如何转义属性。它使用内部的XmlTextEncoder类...



我的方法我目前是usig这样的信息:

  public static string XmlEscapeAttribute(string unescaped)
{
if(String.IsNullOrEmpty(unescaped))return unescaped;

XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
StringBuilder sb = new StringBuilder();
XmlWriter writer = XmlWriter.Create(sb,settings);

writer.WriteStartElement(a);
writer.WriteAttributeString(a,unescaped);
writer.WriteEndElement();
writer.Flush();
sb.Length - =\/>\".Length;
sb.Remove(0,< a a = \。

return sb.ToString();
}

它的丑陋可能很慢,但它的工作: XmlEscapeAttribute(Foo\r\\\
Bar)
将导致Foo& #xD;& #xA; Bar / p>

Edit2:

  SecurityElement.Escape (未逸出); 

不起作用。



Edit3(final):



使用Lars的所有非常有用的注释,我的最终实现如下所示:



注意 .Replace(\r,& #xD;)替换(\\\
& #xA;);
不需要有效的XMl。这只是一个美容方法!

  public static string XmlEscapeAttribute(string unescaped)
{

XmlDocument doc = new XmlDocument();
XmlAttribute attr = doc.CreateAttribute(attr);
attr.InnerText = unescaped;
//替换是*不*必填!
return attr.InnerXml.Replace(\r,& #xD;)。Replace(\\\
,& #xA;);
}

事实证明,这是有效的XML,将被任何标准兼容XMl-parser:

 < response message =谢谢,
LarsH! />


解决方案

修改您引用的解决方案, >

  public static string XmlEscape(string unescaped)
{
XmlDocument doc = new XmlDocument();
var node = doc.CreateAttribute(foo);
node.InnerText = unescaped;
return node.InnerXml;
}

我所做的只是将CreateElement()更改为CreateAttribute()。
属性节点类型具有InnerText和InnerXml属性。



我没有环境来测试这个,但是我很好奇地知道如果它有效。



更新:或者更简单的说,使用 ,如您所链接的问题的另一个答案所建议的。这将排除引号,因此适用于属性文本。



更新2:请注意回车和换行不需要在属性值中转义,以使XML格式正确。如果您希望他们因为其他原因被转义,可以使用String.replace()来执行,例如

  SecurityElement.Escape (未转义).Replace(\r,& #xD;)。Replace(\\\
,& #xA;);

  return node.InnerXml.Replace(\r,& #xD;)。Replace(\\\
,& #xA;);


I had a look at string escape into XML and found it very useful.

I would like to do a similar thing: Escape a string to be used in an XML-Attribute.

The string may contain \r\n.The XmlWriter class produces something like \r\n -> &#xD;&#xA;

The solution I'm currently using includes the XmlWriter and a StringBuilder and is rather ugly.

Any hints?

Edit1:
Sorry to disappoint LarsH, buy my first approach was

public static string XmlEscapeAttribute(string unescaped)
{
    XmlDocument doc = new XmlDocument();
    XmlAttribute attr= doc.CreateAttribute("attr");
    attr.InnerText = unescaped;
    return attr.InnerXml;
}

It does not work. XmlEscapeAttribute("Foo\r\nBar") will result in "Foo\r\nBar"

I used the .NET Reflector, to find out how the XmlTextWriter escapes Attributes. It uses the XmlTextEncoder class which is internal...

My method I'm currently usig lokks like this:

public static string XmlEscapeAttribute(string unescaped)
{
    if (String.IsNullOrEmpty(unescaped)) return unescaped;

    XmlWriterSettings settings = new XmlWriterSettings();
    settings.OmitXmlDeclaration = true;
    StringBuilder sb = new StringBuilder();
    XmlWriter writer = XmlWriter.Create(sb, settings);

    writer.WriteStartElement("a");
    writer.WriteAttributeString("a", unescaped);
    writer.WriteEndElement();
    writer.Flush();
    sb.Length -= "\" />".Length;
    sb.Remove(0, "<a a=\"".Length);

    return sb.ToString();
}

It's ugly and probably slow, but it does work: XmlEscapeAttribute("Foo\r\nBar") will result in "Foo&#xD;&#xA;Bar"

Edit2:

SecurityElement.Escape(unescaped);

does not work either.

Edit3 (final):

Using all the very useful comments from Lars, my final implementation looks like this:

Note: the .Replace("\r", "&#xD;").Replace("\n", "&#xA;"); is not required for valid XMl. It is a cosmetic measure only!

    public static string XmlEscapeAttribute(string unescaped)
    {

        XmlDocument doc = new XmlDocument();
        XmlAttribute attr= doc.CreateAttribute("attr");
        attr.InnerText = unescaped;
        // The Replace is *not* required!
        return attr.InnerXml.Replace("\r", "&#xD;").Replace("\n", "&#xA;");
    }

As it turns out this is valid XML and will be parsed by any standard compliant XMl-parser:

<response message="Thank you,
LarsH!" />
解决方案

Modifying the solution you referenced, how about

public static string XmlEscape(string unescaped)
{
    XmlDocument doc = new XmlDocument();
    var node = doc.CreateAttribute("foo");
    node.InnerText = unescaped;
    return node.InnerXml;
}

All I did was change CreateElement() to CreateAttribute().The attribute node type does have InnerText and InnerXml properties.

I don't have the environment to test this in, but I'd be curious to know if it works.

Update: Or more simply, use SecurityElement.Escape() as suggested in another answer to the question you linked to. This will escape quotation marks, so it's suitable for using for attribute text.

Update 2: Please note that carriage returns and line feeds do not need to be escaped in an attribute value, in order for the XML to be well-formed. If you want them to be escaped for other reasons, you can do it using String.replace(), e.g.

SecurityElement.Escape(unescaped).Replace("\r", "&#xD;").Replace("\n", "&#xA;");

or

return node.InnerXml.Replace("\r", "&#xD;").Replace("\n", "&#xA;");

这篇关于字符串转义为XML-Attribute的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 23:40