`
webcode
  • 浏览: 5940633 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

关于xml编码问题在VB,PHP,JAVA下的解决方案

阅读更多

最近碰到一个项目,需要将申报文件存成XML的格式,编码问题着实让我头疼了一会。现在全部统一成UTF-8编码。具体在各种语言下的操作

这里,我用DOM进行XML解析,应为它简单。

1 客户首先使用VB进行编辑表单,生成一个apply.xml文件。

在VB中,使用MSXML 4.0。如果不设定编码方式,保存的时候,文件默认就是UTF-8编码

Set dom = CreateDOM
Set node = dom.createProcessingInstruction("xml", "version='1.0'")
dom.appendChild node
Set node = Nothing

2 接下来,客户将这个XML通过Web上传到服务器

在PHP中,XMLDOM只支持UTF-8作为默认编码。所以生成的XML文件,上传以后可以直接解析这个文件,获得一些信息

if (!$dom = domxml_open_mem($content)) {
$t->assign('msg', "文件解析错误!");
$t->render('noavailable.html', PAGE_TITLE, 'wrap.html');
exit;
}

接下来,要将这个文件存到数据库里面,因为数据库使用MS Sql Server,它不支持UTF-8的数据结构,所以将整个文件以二进制的方式存到数据库里面,这里让我搞了半天的就是二进制文件的存放方式,如果是mysql,那不需要做任何转换就可以直接存了,但是mssql不行,原因是:

This is because the MSSQL parser makes a clear distinction between binary an character constants. You can therefore not easilly insert binary data with "column = '$data'" syntax like in MySQL and others.

The MSSQL documentation states that binary constants should be represented by their unquoted hexadecimal byte-string. That is.. to set the binary column "col" to contain the bytes 0x12, 0x65 and 0x35 you shold do "col = 0x126535" in you query.

具体操作如下:

//读取上传的文件
$original = $_FILES['content']['name'];
if (!empty($original)) {
if ($_FILES['content']['type'] == "text/xml") {
$filename = $_FILES['content']['tmp_name'];
$handle = fopen($filename, "rb");
$originalcontent = fread($handle, filesize($filename));

fclose($handle);
}
} //end if(!empty($original))

$originalcontent = unpack("H*hex", $originalcontent); //这步是关键

$db->query("insert into ".TBL_SB_ONLINE_USER." (sb_id, user_id, username, sbmc, content, created_date) values ("
.$newid.", "
.$u.", "
.$db->quote(stripslashes($name)).", "
.$db->quote(stripslashes($sbmc)).", 0x"
.$originalcontent['hex'].", " //注意这里,前面有0x
."'$now')");

3 上传之后,用户也可以在网上对这个文件进行在线编辑,这时需要将这个文件从数据库读出,然后还原成UTF-8编码,再进行解析。虽然我们上面使用了unpack,但读出的时候不需要还原。

$sb = $db->getRow('select sbmc, content from '.TBL_SB_ONLINE_USER." where sb_id = $sb_id");
$originalcontent =$sb[content];

if (!$dom = domxml_open_mem($originalcontent)) {
$t->assign('msg', "文件解析错误!");
$t->render('noavailable.html', PAGE_TITLE, 'wrap.html',true);
exit;
}

$context = xpath_new_context($dom);

$xpath = $context->xpath_eval("//material/xm");
$t->assign('xm',iconv("UTF-8","GBK",$xpath->nodeset[0]->get_content()));

读出的时候,mssql除了用于 SQL Server 的 Microsoft OLE DB 提供程序和 SQL Server ODBC 驱动程序自动将 @@TEXTSIZE 设置为最大值 2 GB。其他的都是4096 (4 KB),所以用PHP访问时候,务必将下面打开mssql.textlimit = 2147483647
mssql.textsize = 2147483647

4 后台用VB,要解析该函数需要添加以下代码,用来将byte()转换成utf-8编码

Public Declare Function MultiByteToWideChar Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As Long, _
ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long

Public Const CP_UTF8 = 65001

Public Function UTF8_Decode(bUTF8() As Byte) As String
Dim lRet As Long
Dim lLen As Long
Dim lBufferSize As Long
Dim sBuffer As String
Dim bBuffer() As Byte
lLen = UBound(bUTF8) + 1
If lLen = 0 Then Exit Function
lBufferSize = lLen * 2
sBuffer = String$(lBufferSize, Chr(0))
lRet = MultiByteToWideChar(CP_UTF8, 0, VarPtr(bUTF8(0)), lLen, StrPtr(sBuffer), lBufferSize)
If lRet <> 0 Then
sBuffer = Left(sBuffer, lRet)
End If
UTF8_Decode = sBuffer
End Function

具体读数据库的操作是

Dim varcontent() As Byte
varfilesize = mrc.Fields("content").ActualSize
varcontent = mrc.Fields("content").GetChunk(varfilesize)
content = UTF8_Decode(varcontent)

xmlDoc.async = False
xmlDoc.resolveExternals = False
xmlDoc.loadXML (content)
If (xmlDoc.parseError.errorCode <> 0) Then
Dim myErr
Set myErr = xmlDoc.parseError
MsgBox ("发生错误 " & myErr.reason)
Else
xmlDoc.setProperty "SelectionLanguage", "XPath"

5后台,在Java里面就更好操作了,将读出的数据变成byte[],然后转换成UTF-8的字符串。

当然,事事都有小窍门。关于utf-8的xml存到mssql里面,还有一种歪门邪道,那就是将读入的utf-8的xml (三字节)转换成GBK(2字节),这样双字节的文本保存到mssql的text类型字段里面。从VB读取得时候,msxml能自动识别gbk。从php读取得时候,将GBK再转成utf-8,给domxml解析。哈哈

最后要说的是,PHP的确是一个非常强大的脚本语言,如果开发PHP过程中遇到难以解决,google都不容易搜到的问题,大家直接上php.net的在线文档,文档里面通常有很多好心人将自己的使用心得写在上面,非常有帮助。

分享到:
评论

相关推荐

    java在线解析xmljava在线解析xmljava在线解析xmljava在线解析xml

    java在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在线解析xml...java在线解析xmljava在线解析xmljava在线解析xmljava在线解析xmljava在

    vb6XML读写

    vb中读写XML文件实例Dim XMLDoc As DOMDocument Dim root As IXMLDOMNode Dim xlst As IXMLDOMNodeList, xlst1 As IXMLDOMNodeList Dim xn As IXMLDOMNode Dim xnf As IXMLDOMNode Dim xe As IXMLDOMElement Set ...

    java http 发送xml报文(java发送xml报文实例+参数)

    java http 发送xml报文(java发送xml报文实例+参数)java http 发送xml报文java http 发送xml报文(java发送xml报文实例+参数)

    java 不用第三方类库解码编码Xml

    java 不用第三方类库解码编码Xml,验证可用

    VB.net读取XML标签值

    VB.net读取XML标签值,两种方法,一是加载XML字符串,一是加载XML文件,然后再从节点路径中读TAG第一个匹配值

    java http 发送xml报文

    java http 发送xml报文java http 发送xml报文java http 发送xml报文java http 发送xml报文java http 发送xml报文java http 发送xml报文java http 发送xml报文java http 发送xml报文java http 发送xml报文java http ...

    用VB 6操作XML文件

    用VB操作XML '生成一个XML DOMDocument对象 Set xmlDOMDocument = New MSXML2.DOMDocument '生成根节点,在此我们称它为“爷爷辈”节点 Set Root_Node = xmlDOMDocument.createElement("Root") Set ...

    java解析XML四种方案

    java解析XML四种方案: DOM 实现方法; DOM4J实现方法; JDOM实现方法; SAX实现方法;

    Java与XML(PDF)

    展示了如何将两者结合起来构建动态生成内容的WEB站点,如何编写具有更低开销的信息共享和数据交换的企业级软件,以及如何对需要可移植数据的其他问题开发简单和高效的解决方案。本书第二版还包括SAX和DOM的高级知识...

    JAVA 解析XML生成XML文档实例

    JAVA 解析XML和生成XML文档源码。比较全 1.DOM生成和解析XML文档 2.SAX生成和解析XML文档 3.DOM4J生成和解析XML文档 4.JDOM生成和解析XML

    Java解析XML工具类--(java源码)

    * 解析某个xml文件,并在内存中创建DOM树 * @param xmlFile 要解析的XML文件 * @return 解析某个配置文件后的Document * @throws Exception xml文件不存在 */ public static Document parse( String xml...

    vb.net对xml文件进行操作

    通过vb.net对xml文件进行创建、插入、修改和删除操作,代码简洁,针对性强。

    java导入导出xml文件

    这是一个java对xml操作的两个类,xml文件的节点都是已知的,都需要提前指定.

    java解析XML文件

    java解析XML文件java解析XML文件java解析XML文件java解析XML文件java解析XML文件java解析XML文件

    Xml 解决方案开发实务

    专为任何对于下一代企业解决方案有兴趣的读者所设计的。如果你想了解XML(可扩展标记语言,Extensible Markup Language),学习使用XML 来设计企业对企业(B2B)的沟通管道,了解Simple Object Access Protocol ...

    vb读取xml文件节点值操作实例

    VB读取XML文件的操作实例,演示读取XML各个定义键的值。程序是一个专一读取XML文件的VB类,并没有使用微软的XML.DLL。因此比较有参考价值,很不错。

    XML解析器VB

    XML解析器VB

    java读写xml文件

    java读写xml文件 java读写xml文件 java读写xml文件 java读写xml文件 java读写xml文件 java读写xml文件

    java 通过模板生成 xml,发送报文

    java 通过模板生成 xml,发送报文

    VB_XML.rar_ VB_XML_VB speeaksdk xml_vb xml_xml_xml vb

    VB使用xml的源代码。自己编写的。很不错。一看就懂

Global site tag (gtag.js) - Google Analytics