C#注册表以XML字符无效的问题(c# Registry to XML Invalid charac

2019-09-19 13:09发布

试图创建注册表XML文件时,我有一个问题。 在我的笔记本电脑(W7 64B)它工作正常,生成的XML文件,但另一台计算机上(XP 32B)抛出一个异常:“” System.ArgumentException,十六进制数值为0x00,是一个无效字符。 我看过一些关于它的有用的东西,但我不知道如何在这种情况下解决,这里是代码:

        try
        {

        string regPath = "SOFTWARE\\IPS";
        XElement xRegRoot = new XElement("Root", new XAttribute("Registry", regPath));

        ReadRegistry(regPath, xRegRoot);

        string xmlStringReg = xRegRoot.ToString();

        XmlDocument docR = new XmlDocument();
        docR.LoadXml(xmlStringReg);

            docR.Save(AppDomain.CurrentDomain.BaseDirectory + "\\_RegistryList.xml");
        }
        catch (System.Exception ex)
        {
            Console.WriteLine(ex.ToString());
            LogToFile(ex.ToString());
        }

    private static void ReadRegistry(string keyPath, XElement xRegRoot)
    {
        string[] subKeys=null;
        RegistryKey HKLM = Registry.LocalMachine;
        RegistryKey RegKey = HKLM.OpenSubKey(keyPath);

        try
        {
            subKeys = RegKey.GetSubKeyNames();
            foreach (string subKey in subKeys)
            {
                string fullPath = keyPath + "\\" + subKey;                    
                Console.WriteLine("\r\nKey Name  | " + fullPath);
                LogToFile("Key Name  | " + fullPath);

                XElement xregkey = new XElement("RegKeyName", new XAttribute("FullName", fullPath), new XAttribute("Name", subKey));
                xRegRoot.Add(xregkey);
                ReadRegistry(fullPath, xRegRoot);
            }

            string[] subVals = RegKey.GetValueNames();
            foreach (string val in subVals)
            {
                string keyName = val;
                string keyType = RegKey.GetValueKind(val).ToString();
                string keyValue = RegKey.GetValue(val).ToString();

                Console.WriteLine("Key Value | " + keyType + " | " + keyName + " | " + keyValue);
                LogToFile("Key " + keyType + " | " + keyName + " | " + keyValue);
                XElement xregvalue = new XElement("RegKeyValue", new XAttribute("keyType", keyType), new XAttribute("keyName", keyName), new XAttribute("keyValue", keyValue));
                xRegRoot.Add(xregvalue);
            }
        }
        catch (System.Exception ex)
        {
            Console.WriteLine(ex.ToString());
            LogToFile(ex.ToString());
        }
    }

提前致谢。

Answer 1:

这里有一些小的改进,一)编制,和b)处理代理对:

    /// <summary>
    /// Remove illegal XML characters from a string.
    /// </summary>
    public static string SanitizeString(string s)
    {
        if (string.IsNullOrEmpty(s))
        {
            return s;
        }

        StringBuilder buffer = new StringBuilder(s.Length);

        for (int i = 0; i < s.Length; i++)
        {
            int code;
            try
            {
                code = Char.ConvertToUtf32(s, i);
            }
            catch (ArgumentException)
            {
                continue;
            }
            if (IsLegalXmlChar(code))
                buffer.Append(Char.ConvertFromUtf32(code));
            if (Char.IsSurrogatePair(s, i))
                i++;
        }

        return buffer.ToString();
    }

    /// <summary>
    /// Whether a given character is allowed by XML 1.0.
    /// </summary>
    private static bool IsLegalXmlChar(int codePoint)
    {
        return (codePoint == 0x9 ||
            codePoint == 0xA ||
            codePoint == 0xD ||
            (codePoint >= 0x20 && codePoint <= 0xD7FF) ||
            (codePoint >= 0xE000 && codePoint <= 0xFFFD) ||
            (codePoint >= 0x10000/* && character <= 0x10FFFF*/) //it's impossible to get a code point bigger than 0x10FFFF because Char.ConvertToUtf32 would have thrown an exception
        );
    }


Answer 2:

我做了一些实验:

  • new XElement("foo\x00bar")抛出的建设。
  • new XAttribute("foo\x00bar", "baz")抛出的建设。
  • new XText("foo\x00bar")只抛出时调用.ToString()

new XAttribute("foo", "bar\x00baz")等同于new XAttribute("foo", new XText("bar\x00baz"))所以它不会对建筑扔。

我没做任何的注册表的方法返回与空字符的字符串,但你应该能够找到这个地方返回自己。



Answer 3:

你可以阅读更多关于它在这里: http://seattlesoftware.wordpress.com/2008/09/11/hexadecimal-value-0-is-an-invalid-character/

而更多关于它在这里: 的XElement和UTF-8的问题

XML字符的有效列表在这里http://en.wikipedia.org/wiki/Valid_characters_in_XML

但本质上,你可以通过连载之前移除非法字符修复

/// <summary>
/// Remove illegal XML characters from a string.
/// </summary>
public string SanitizeXmlString(string xml)
{
    if (string.IsNullOrEmpty(value))
    {
        return value;
    }

    StringBuilder buffer = new StringBuilder(xml.Length);

    foreach (char c in xml)
    {
        if (IsLegalXmlChar(c))
        {
            buffer.Append(c);
        }
    }

    return buffer.ToString();
}

/// <summary>
/// Whether a given character is allowed by XML 1.0.
/// </summary>
public bool IsLegalXmlChar(int character)
{
    return
    (
         character == 0x9 /* == '\t' == 9   */          ||
         character == 0xA /* == '\n' == 10  */          ||
         character == 0xD /* == '\r' == 13  */          ||
        (character >= 0x20    && character <= 0xD7FF  ) ||
        (character >= 0xE000  && character <= 0xFFFD  ) ||
        (character >= 0x10000 && character <= 0x10FFFF)
    );
}


文章来源: c# Registry to XML Invalid character issue