子弹点不替换 - csv到xml

时间:2015-05-09 19:18:11

标签: c#

我正在读取CSV文件并将其转换为XML。问题是,子弹点,连字符等。我试图替换"•"以及其他没有被观看的角色#34;有效。当生成XML时,项目符号点表示为正方形,事实上,任何未被识别的都是正方形。 当我复制" square"从生成的XML,所有"特殊"字符是"看到"作为黑色钻石,里面有问号。在XML输出中,它表示为"�"。 我试过了:

int i = (int)'•';
Console.WriteLine(i);

我看到的值为8226。

所以我尝试用" html替换\u8226替换子弹"所以它会正常显示,但这不起作用。

我这样读了原始的CSV:

string[] csvfile = File.ReadAllLines(inputFile).Skip(1).ToArray();

我正在阅读的文件不会很大,所以这就是我正在阅读数组的原因。

然后我分开","给我转换为XML元素的列。 如果我在Excel中打开文件并通过Excel手动替换,没有问题。我得到了预期的xml输出。我想以编程方式执行此操作。我在使用常规文本在xml元素中替换时没有任何问题,例如:

new XElement("elementName", columns[14].ToLower().Replace("yes", "1")

如果我尝试:

new XElement("elementName", columns[14].ToLower().Replace("•", "htmlReplacement")

没有任何改变。

任何见解都会很棒!

以下是我正在使用的代码:

//上面的正则表达式以下替换 - 这可行

        string inputFile = @"pathTo.csv";

        string[] csvfile = File.ReadAllLines(inputFile).Skip(1).ToArray();

        XNamespace xsi = XNamespace.Get("http://www.w3.org/2001/XMLSchema-instance");
        XNamespace xsiNsl = XNamespace.Get("something.xsd");

        XElement jobs = new XElement("Root",
            new XAttribute(XNamespace.Xmlns + "xsi", xsi.NamespaceName),
            new XAttribute(xsi + "noNamespaceSchemaLocation", xsiNsl),

            from line in csvfile
            //let columns = line.Replace(", ", ", ").Replace(",0", ",0").Split(',')

            let columns = Regex.Replace(Regex.Replace(Regex.Replace(Regex.Replace(line, dPat, rdPat), dPat2, rdPat2), dPat3, rdPat3), dPat4, rdPat4).Split(',')

            select new XElement("item",
                new XElement("column1", columns[0]),
                new XElement("Column2", columns[1]),
                new XElement("Column3", new XCData(columns[2].Replace("–", "-").Replace("•", "•").Replace("®", "®").Replace("©", "©"))),
                new XElement("Column4", new XCData(columns[3].Replace("–", "-").Replace("•", "•").Replace("®", "®").Replace("©", "©"))),
                new XElement("Column5", new XCData(columns[4].Replace("–", "-").Replace("\x0095", "• ").Replace("®", "®").Replace("©", "©").Replace("\n\n", "").Replace("\"", ""))),
                new XElement("column6", columns[5]),
                new XElement("column7", columns[6].Replace("/", "-")),
                new XElement("column8", columns[7]),
                new XElement("column 9", columns[8].Replace("$", "").Replace(" ", "").Replace(".00", "")),
                new XElement("column10", columns[9]),
                new XElement("column11", columns[10].Replace("/", "-")),
                new XElement("column12", columns[11].Replace("/", "-")),
                new XElement("column13", columns[12].ToLower().Replace("yes", "1").Replace("no", "0")),
                new XElement("column14", columns[13].ToLower().Replace("yes", "1").Replace("no", "0")),
                new XElement("column15", columns[14].ToLower().Replace("yes", "1").Replace("no", "0")),
                new XElement("column16", columns[15].ToLower().Replace("yes", "1").Replace("no", "0")),
                new XElement("column17", columns[16].ToLower().Replace("yes", "1").Replace("�", "0")),
                new XElement("column18", columns[17]),
                new XElement("column19", columns[18]),
                new XElement("column20", columns[19])));

        jobs.Save(@"outputPathFor.xml");

除了未替换的无法识别的字符外,创建的xml是预期的。我确实尝试使用十六进制,但也没有替换它们。

谢谢!

1 个答案:

答案 0 :(得分:0)

您可能希望确保使用更通用的方法从输入中转义unicode字符(而不是执行string.Replace调用)。像下面的方法:

public static IEnumerable<string> UnicodeXmlEscape(IEnumerable<string> input)
{
    var sb = new StringBuilder();
    foreach (var line in input)
    {
        // Loop through each character in the line to see if it
        // needs escaping.
        for (int i = 0; i < line.Length; i++)
        {
            if (char.IsSurrogatePair(line, i))
                // Escape in "&#xABC1234E" format
                sb.AppendFormat(@"&#x{0:x8}", char.ConvertToUtf32(line, i++)); // i++ to skip next one.
            else
            {
                int ci = char.ConvertToUtf32(line, i);
                if (ci > 127) 
                    // Escape in "&#xAB12" format
                    sb.AppendFormat(@"&#x{0:x4}", ci);
                else // regular ASCII
                    sb.Append(line[i]);
            }
        }
        yield return sb.ToString();
        sb.Clear();
    }
}

所以这个:

var escaped = UnicodeXmlEscape(new [] { 
    @"I'm trying to replace • along with other characters that are not being" 
});
foreach (var line in escaped)
    Console.WriteLine(line);

将产生以下输出:

I'm trying to replace &#x2022 along with other characters that are not being

请注意,某些unicode字符在xml(http://www.w3.org/TR/unicode-xml/)中不合法。上面的代码不会检查它们的发生。

如何在代码中使用此功能

在你的代码中你可以简单地使用它来处理从输入文件读取的每一行和&#34; xml unicode escape&#34;它们。

var csvfile = UnicodeXmlEscape(File.ReadLines(inputFile).Skip(1)).ToArray();

要获取正确的转义行,您可以将其用作列拆分的输入。以后不再需要String.Replace