首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >插入带有编码SHIFT-JIS错误的XML文件

插入带有编码SHIFT-JIS错误的XML文件
EN

Stack Overflow用户
提问于 2017-12-11 09:18:39
回答 1查看 1K关注 0票数 0

我有一个使用SHIFT-JIS编码的XML文件,如下所示:

代码语言:javascript
复制
<?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></データベース></海外管理ファイル>

我使用SQL存储过程将其插入到SQL表中:

代码语言:javascript
复制
alter PROCEDURE [dbo].[proc_TBL_PO_H_LoadXMLPO]
@xml  XML
AS  
    BEGIN
        SET NOCOUNT ON;
        INSERT INTO [ENVIETNAMPO].[dbo].[TBL_PO_H]
              SELECT
                  TBL_PO_H.value('(PO番号/text())[1]','varchar(13)') AS PO番号, --TAG
                  TBL_PO_H.value('(PO発行日/text())[1]','varchar(10)') AS PO発行日                  
              FROM
                 @xml.nodes('/海外管理ファイル/データベース/PO/Tbl_PO_H/DATA')AS TEMPTABLE(TBL_PO_H)      
    END

Load按钮的C#代码:

代码语言:javascript
复制
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文件。请帮帮我。谢谢!

代码语言:javascript
复制
System.Data.SqlClient.SqlException 0x80131904: parsing XML Line 1, character 59. Cannot swicth I- code ....
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-11 21:05:54

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

有些事情要知道:

  • 在C#中,XML要么是您看到的字符串,要么是像XmlDocument这样的按层次组织的文档。
  • 在任何情况下,当您将XML传递到数据库(序列化)时,它会被转换为它的字符串表示形式。
  • C#中的所有字符串都是unicode。您可以定义特殊的编码,并将编码的字符串转换为字节数组,但是字符串类型本身在任何情况下都是unicode。
  • Server将接受该字符串并将其解析为原生XML数据类型,该数据类型在内部是一个层次结构表。
  • XML的所有部分(标记名称、内容、.)存储在SQL-Servers NVARCHAR中,这是一种unicode (实际上是UCS-2)。
  • 在任何情况下,Server都不允许将此声明与XML一起存储。无论如何它都会被省略..。

所以这里发生了什么:

您传递了一个字符串,实际上是unicode,但是字符串告诉引擎:不,我是SHIFT-JIS__!-这条绳子是个骗子

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

但是,在C#和数据库之间,没有必要搞砸:字符串是纯unicode,将被带入(几乎)普通unicode。

简单的解决办法:

在没有<?xml blah?>声明的情况下传递XML。

更新

关于你的问题“如何剥夺声明”?

当你得到XML的时候

string xml = File.ReadAllText(xmlfilePath, Encoding.GetEncoding("SHIFT-JIS"));

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

您可以在这里使用任何字符串方法:

  • 使用.IndexOf()查找?> (声明结束),并使用.Substring()完全删除声明
  • 使用.Replace()将编码更改为encoding="utf-16"
  • 用RegEx,你喜欢什么.

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47749588

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档