有一个xml的数据文件。其对应的dtd文件中对所有的属性定义全部是CDATA,数据文件中所有属性的内容全部用双引号包含(不好意思,不太懂xml不知道是不是所有的字段内容都要引号的)。
现在检测出其中属性内容凡是中文或者只有一个0的,统统检测为varNull类型的variant,这是为什么?
难道数字或者英文跟中文字符在variant单元中被判定的类型还不一样的?

解决方案 »

  1.   

    <?xml version="1.0" encoding="gb2312" ?> 
    ↑検査你的xml文件encoding、再看dtd文件的内容。
    都可用「XML Mapping」工具査看検測。
      

  2.   

    encoding="GBK"
    这个有影响吗?
      

  3.   

    补充一点:发现我的一个打印节点的函数能够正常工作
    两者的区别是打印函数中我用了...node[i].nodevalue,而检测函数中因为要确定是哪一个属性,用了...node['str'].nodevalue。
    当检测出类型为varNull,即检测函数中直接赋值给一个字符串要出错的情况下,我可以用打印函数把整个节点和那个属性的类型打印出来(打印函数中肯定是要读取那个属性的内容的)
      

  4.   

    继续补充:我把xml中的encoding改了还是不行。
    另外我在检测函数中用indexof先取索引,然后再用node[i]的形式来取数还是不行,郁闷,不知道原因了撒
      

  5.   

    NI越説我越不明白NI的目的、実在不行貼出NI的「XML文件」
    写明目的(NI要的結果)...
     
    Help you up!
      

  6.   

    xml文件太大,只贴dtd出来吧:
    <?xml version="1.0" encoding="GBK"?><!ELEMENT SCHEMA (SWJG)>
    <!ATTLIST SCHEMA
    NAME CDATA #REQUIRED
    CHSNAME CDATA #REQUIRED
    SSSQ CDATA #REQUIRED
    CRC CDATA #REQUIRED
    >
    <!ELEMENT SWJG (SWJG+ | TAXPAYER*)>
    <!ATTLIST SWJG
    SWJGID CDATA #REQUIRED
    SWJGMC CDATA #REQUIRED
    HZRQ CDATA #REQUIRED
    RECORDCOUNT CDATA #REQUIRED
    >
    <!--以下部分与YSFPCGLJK.DTD同-->
    <!ELEMENT TAXPAYER (Records)>
    <!--TAXPAYER属性部分由系统统一定义-->
    <!ATTLIST TAXPAYER
    SWSBH CDATA #REQUIRED
    NSRMC CDATA #REQUIRED
    SBRQ CDATA #REQUIRED
    RECORDCOUNT CDATA #REQUIRED
    CJLX CDATA #REQUIRED
    CJRDM CDATA #REQUIRED
    CJRMC CDATA #REQUIRED
    >
    <!ELEMENT Records (Record)*>
    <!ELEMENT Record EMPTY>
    <!ATTLIST Record
        FPHM    CDATA   #REQUIRED
        KPRQ    CDATA   #REQUIRED
        KPJE        CDATA   #REQUIRED
        XFSWSBH   CDATA   #REQUIRED
        XFNSRMC      CDATA   #REQUIRED    
        GFSWSBH   CDATA   #REQUIRED
        GFNSRMC      CDATA   #REQUIRED    
    >
    ------------------------------------------------------------
    再贴我的两个函数的代码出来
    GetNodeStr函数就是复原出一个节点的文本
    function TForm1.GetNodeStr(inode:IXMLNode):string;
    var
    icount:integer;
    value:string;
    begin
        icount:=0;
        result:='<'+inode.NodeName;
        while icount<inode.AttributeNodes.Count do
        begin
            if inode.AttributeNodes.Nodes[icount].NodeValue<>Null then value:=inode.AttributeNodes.Nodes[icount].NodeValue;
            result := result + ' ' + inode.AttributeNodes.Nodes[icount].NodeName+'="'+value + '"';
            inc(icount);
        end;
        result := result + '>';
    end;checknode函数是递归调用检查所有数据合法性:
    procedure TForm1.checknode(inode:IXMLNode);
    var
    nullvalue:boolean;
    Nodestr,temp,GFSWSBH,XFSWSBH,fphm:string;
    i:integer;
    begin
        nullvalue:=False;
        Nodestr:=inode.NodeName;
        if Nodestr='SWJG' then
        begin
            //机关代码位数不为6,7,9,11位的,且头几位代码匹配,错误号:1
            Nodestr:=inode.AttributeNodes.Nodes['SWJGID'].NodeValue;
            if not(
            ((length(Nodestr)=6) and (AnsiMidStr(Nodestr,1,2)='33')) or
            ((length(Nodestr)=7) and (AnsiMidStr(Nodestr,1,3)='233')) or
            ((length(Nodestr)=9) and (AnsiMidStr(Nodestr,1,3)='233')) or
            ((length(Nodestr)=11) and (AnsiMidstr(Nodestr,1,3)='233'))
            )
            then
            begin
                temp:=ErrInsertstr(inode,1);
                ADOConn.Execute(temp);
            end;
        end
        else if Nodestr='TAXPAYER' then
        begin
            //检查合法性
        end
        else if UpperCase(Nodestr)='RECORD' then
        begin
            //先把NodeValue为空的情况剔除,NodeValue为空对字符串赋值会出错
            if inode.AttributeNodes.Nodes['GFSWSBH'].NodeValue=Null then
            begin
                showmessage(GetNodeStr(inode));//这里算是示例,就在这里调用getnodestr获取inode节点信息
                nullvalue:=true;
                ADOConn.Execute(ErrInsertStr(inode,2))
            end
    {        else if inode.AttributeNodes.Nodes['XFSWSBH'].NodeValue=Null then
            begin
                nullvalue:=true;
                ADOConn.Execute(ErrInsertStr(inode,3))
            end}
            else if inode.AttributeNodes.Nodes['FPHM'].NodeValue=Null then
            begin
                nullvalue:=true;
                ADOConn.Execute(ErrInsertStr(inode,4))
            end;        if not nullvalue then
            begin
                //购方纳税人识别号位数错误,不是15或者18位
    //就是下面这条语句,如果没有上面=Null的判断,碰到是中文或者其他我不清楚的数据会报错,
    //检测属性值为varNull,即不可识别。但是我在上面那几句判断=Null的语句里面
    //加showmessage(GetNodeStr(inode));可以打印出节点的完整信息。但是这里我先用
    //indexof('str')的方法获取一个gi索引,在用...Nodes[gi].NodeValue取值还是不行
    //就是说同样的节点,在这个函数里面判断为varNull,但是在GetNodeStr函数里面就不是varNull类型
    //可以很顺利的取值,然后构造字符串
                GFSWSBH:=inode.AttributeNodes.Nodes['GFSWSBH'].NodeValue;
                if (length(trim(GFSWSBH))<>15) and (length(trim(GFSWSBH))<>18) then
                begin
                    temp:=ErrInsertStr(inode,2);
                    ADOConn.Execute(temp);
                end;
                //销方纳税人识别号超长
        {        XFSWSBH:=inode.AttributeNodes.Nodes['XFSWSBH'].NodeValue;
                if {(length(XFSWSBH)=0) or (length(XFSWSBH)>30) then
                begin
                    temp:=ErrInsertStr(inode,3);
                    ADOConn.Execute(temp);
                end;}
                //发票号码为空
                fphm:=inode.AttributeNodes.Nodes['FPHM'].NodeValue;
                if length(fphm)=0 then
                begin
                    temp:=ErrInsertStr(inode,4);
                    ADOConn.Execute(temp);
                end;
            end;
        end;//    if test then showmessage(booltostr(test));
        for i:=0 to inode.ChildNodes.Count - 1 do
            checknode(inode.ChildNodes.Nodes[i]);
    end;