C# 插入编码为SHIFT-JIS错误的XML文件

C# 插入编码为SHIFT-JIS错误的XML文件,c#,sql-server,xml,tsql,character-encoding,C#,Sql Server,Xml,Tsql,Character Encoding,我有一个XML文件,其SHIFT-JIS编码如下: <?xml version="1.0" encoding="SHIFT-JIS" standalone="yes"?> <海外管理ファイル><PO番号>GV05097</PO番号><データベース><PO><Tbl_PO_H PO番号="GV05097"><DATA><PO番号 TYPE="200" LENGTH="13">GV05097&

我有一个XML文件,其SHIFT-JIS编码如下:

<?xml version="1.0" encoding="SHIFT-JIS" standalone="yes"?>
<海外管理ファイル><PO番号>GV05097</PO番号><データベース><PO><Tbl_PO_H PO番号="GV05097"><DATA><PO番号 TYPE="200" LENGTH="13">GV05097</PO番号></DATA></Tbl_PO_H></PO></データベース></海外管理ファイル>
加载XML按钮的C#代码:

string pathUser = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
            string pathDesktop = Path.Combine(pathUser, "Desktop");
            var xmlfilename = string.Empty;
            var xmlfilePath = string.Empty;
            //var dt = new DataTable();           
            var sqlConn = new SqlConnection(strConStr);
            try
            {
                    openFileDialog1.InitialDirectory = @pathDesktop;
                    openFileDialog1.Title = "Browse XML PO File";
                    openFileDialog1.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
                    openFileDialog1.CheckFileExists = true;
                    openFileDialog1.CheckPathExists = true;
                    openFileDialog1.ShowHelp = true;
                    openFileDialog1.FileName = "*.xml";
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    xmlfilename =openFileDialog1.SafeFileName;
                    xmlfilePath = pathDesktop +"\\"+ xmlfilename;
                    string xml = File.ReadAllText(xmlfilePath, Encoding.GetEncoding("SHIFT-JIS"));
                    sqlConn.Open();

                    var cmd = new SqlCommand("proc_TBL_PO_H_LoadXMLPO", sqlConn);
                    cmd.CommandType = CommandType.StoredProcedure;
                    cmd.Parameters.AddWithValue("@xml", xml);
                    SqlCommand arithabortCommand = new SqlCommand("SET ARITHABORT ON", sqlConn);
                    arithabortCommand.ExecuteNonQuery();  
                    cmd.ExecuteNonQuery(); 
                    sqlConn.Close();
                }

                    MessageBox.Show("PO XML File has been imported successfully.", "Information",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());
            }
但在加载时,出现如下错误,我尝试将编码正确的XML文件读取为XML文件。请帮帮我。谢谢大家!

System.Data.SqlClient.SqlException 0x80131904: parsing XML Line 1, character 59. Cannot swicth I- code ....

如果我理解正确,那么您就是在将XML原样从C#传递到SQL Server存储过程中。您没有说明实际的RDBMS,但我假设这是SQL Server(由于关于编码的“开关”的错误消息)。希望这是正确的,如果不是,这可能对其他数据库也有帮助

要知道的一些事情:
  • 在C#XML中,要么是您看到的字符串,要么是像
    XmlDocument
    这样的分层组织文档
  • 在任何情况下,当您将XML传递给数据库时,XML都会转换为其字符串表示形式(序列化)
  • C#中的所有字符串都是unicode。您可以定义特殊编码并将编码字符串转换为字节数组,但字符串类型本身在任何情况下都是unicode
  • SQLServer将获取字符串并将其解析为原生XML数据类型,这是内部的层次结构表
  • XML的所有部分(标记名、内容等)都存储在SQL Server
    NVARCHAR
    ,这是一种unicode(
    UCS-2
  • 无论如何,SQL Server都不允许您将此声明与XML一起存储。无论如何,它都将被省略
那么这里发生了什么: 你交出一个字符串,实际上是unicode,但是字符串告诉引擎:不,我是
SHIFT-JIS
!。这根绳子是个骗子

仅当您将此XML存储在任何字节容器(如文件)中并且希望告诉读者如何解码内容时,才需要此声明

但是在C#和数据库之间,没有必要乱来:字符串是纯unicode,将被(几乎)纳入纯unicode

简易解决方案: 传递不带
声明的XML

使现代化 关于你的问题“如何去除声明”

当您获得XML时

stringxml=File.ReadAllText(xmlfilePath,Encoding.GetEncoding(“SHIFT-JIS”)

您没有XML(本机类型),但有一个看起来像XML的(unicode)字符串

您可以在此处使用任何字符串方法:

  • 使用
    .IndexOf()
    查找
    ?>
    (声明结尾),并使用
    .Substring()
    完全删除声明
  • 使用
    .Replace()
    将编码更改为
    encoding=“utf-16”
  • 使用正则表达式,无论你喜欢什么

另一方面,您可以将字符串作为
NVARCHAR(MAX)
(SP的参数)传递给存储过程,并在SQL Server尝试将其作为XML之前在那里进行截断。但我建议在C#端解决这个问题。

我认为Shift JIS编码设置使用下划线而不是破折号(与UTF-8不同):
string xml=File.ReadAllText(xmlfilePath,encoding.GetEncoding(“Shift#JIS”)。您能否提供由
xml
string返回的结果来确保?尝试了“shift_jis”和string xml=File.ReadAllText(xmlfilePath,Encoding.GetEncoding(932));但是它仍然会得到相同的错误,您的问题与存储过程中用作参数的
XML
数据类型有关。尝试摆脱
AddWithValue
并使用显式数据类型:
cmd.Parameters.Add(“@xml”,SqlDbType.xml)。Value=xml。这个问题可能类似于:我试过了,但没有成功。我想我必须尝试用C代码消除XML头。这将解决我的问题事实上,删除
encoding=“SHIFT-JIS”
似乎可以解决XML转换错误(使用MSSQL 2008进行测试)。我遇到了一个问题,我们从其他分支接收XML文件,因此我不想手动删除。有没有办法用C#代码跳过这个标题?我现在解决了这个问题,但我面临的另一个问题是将XML数据类型0.009转换为SQL中的货币类型。我使用了TBL_PO_M.value('(下代)[1] “,“钱”)作为下代 但不能。Thanks@user3035133请避免后续问题。下次请开始一个新问题。这很简单:在
T-SQL
中,您必须在所有文本前放置
N
。请尝试以下操作:
SELECT'(下代)[1] “没有,没有”(下代)[1] '与_N
System.Data.SqlClient.SqlException 0x80131904: parsing XML Line 1, character 59. Cannot swicth I- code ....