c# - 项目符号点不替换 - csv 到 xml

标签 c#

我正在读取 CSV 文件并将其转换为 XML。问题是,要点、连字符等。我正在尝试将“•”与其他未被“视为”有效的字符一起替换。生成 XML 时,项目符号点表示为正方形,实际上,任何不能识别的都是正方形。 当我从生成的 XML 中复制“正方形”时,所有“特殊”字符都被“视为”内部带有问号的黑色菱形。在 XML 输出中,它表示为“�”。 我试过:

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

我看到一个值 8226。

所以我尝试将 \u8226 替换为“html for bullet”,以便它可以正确显示,但这不起作用。

我是这样阅读原始 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 符合预期。我确实尝试使用十六进制,但也没有取代它们。

谢谢!

最佳答案

您可能希望确保有一种更通用的方式从输入中转义您的 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/)。上面的代码不检查它们的出现。

如何在您的代码中使用它

在您的代码中,您可以像这样简单地使用它,处理从输入文件中读取的每一行,并对它们进行“xml unicode 转义”。

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

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

关于c# - 项目符号点不替换 - csv 到 xml,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30144047/

相关文章:

c# - 在 C# 上编辑 dataGridView 单元格

c# - WPF Dispatcher.InvokeAsync() 异步委托(delegate)的奇怪行为

c# - 将来自网络的图像保存到 Windows Phone 8.1 RT C# 中的已保存图片文件夹

c# - WPF Image : . Source = Clipboard.GetImage() 未显示

c# - 为什么这段多线程代码有时会打印 6?

c# - 将 Window 桌面应用程序转换为 Window 服务

c# - 如何将对象列表传递给无法更改对象属性的方法?

c# - 通过 C# 中的反射获取 'basic' 数据类型而不是奇怪的可空数据类型

c# - 在 Entity Framework 中,当列定义为不可为空时,如何让存储过程返回可为空?

c# - Stringbuilder 到 CSV