返回列表 发帖

[完成]40元从xml提取数据

本帖最后由 lxh623 于 2020-6-23 10:17 编辑

文件夹下有多级子文件夹。总共有近两万个xml文件。附件是例子。来源于大藏经,CBReader 。
比如:
<char xml:id="CB04865">
<charName>CBETA CHARACTER CB04865</charName>
<charProp>
<localName>composition</localName>
<value>[目*丐]</value>
</charProp>
<charProp>
<localName>normalized form</localName>
<value></value>
</charProp>
<mapping type="normal_unicode">U+7704</mapping>
<mapping cb:dec="987905" type="PUA">U+F1301</mapping>
</char>COPY
也没有全部研究,大约有五个字段。CBETA CHARACTER、composition、normalized form、unicode、PUA。
想把字段提取到excel。主要的问题是,后面三个字段不是每一个字都有。(提取不到,可以写为0 。)
如果做成制表符分隔的文本,最好是unicode编码。因为汉字的原因。
谢谢!


链接:https://pan.baidu.com/s/1msOq72fmUsI7vrmrU2bTKw
提取码:qfyg
复制这段内容后打开百度网盘手机App,操作更方便哦

<# :
cls
@echo off
cd /d "%~dp0"
powershell -NoProfile -ExecutionPolicy bypass "Invoke-Command -ScriptBlock ([ScriptBlock]::Create([IO.File]::ReadAllText('%~f0',[Text.Encoding]::Default))) -Args '%~dp0'"
pause
exit
#>
$path=$args[0];
$outfile=$path+'#result.csv';
$enc=[Text.Encoding]::UTF8;
$fs=New-Object System.IO.FileStream($outfile, [System.IO.FileMode]::Create);
$sw=New-Object System.IO.StreamWriter($fs, $enc);
$files=@(dir -liter $path -recurse|?{('.xml' -eq $_.Extension) -and ($_ -is [System.IO.FileInfo])});
for($i=0;$i -lt $files.length;$i++){
    write-host $files[$i].FullName;
    $text=[IO.File]::ReadAllText($files[$i].FullName, $enc);
    $m1=[regex]::matches($text, '<char xml:id="[^"]*?">([\s\S]+?)</char>');
    if($m1.count -ge 1){
        foreach($k in $m1){
            $arr=@('','','','','');
            $a=[regex]::match($k.groups[1].value,'[^>]+(?=</charName>)');
            if($a.success){$arr[0]=$a.groups[0].value;};
            $b=[regex]::match($k.groups[1].value,'composition</localName>\s*?<value>([\s\S]+?)</value>');
            if($b.success){$arr[1]='"'+$b.groups[1].value+'"';};
            $c=[regex]::match($k.groups[1].value,'normalized form</localName>\s*?<value>([\s\S]+?)</value>');
            if($c.success){$arr[2]='"'+$c.groups[1].value+'"';};
            $d=[regex]::match($k.groups[1].value,'<mapping type="[^"]*?unicode">([\s\S]+?)</mapping>');
            if($d.success){$arr[3]=$d.groups[1].value;};
            $e=[regex]::match($k.groups[1].value,'type="PUA">([\s\S]+?)</mapping>');
            if($e.success){$arr[4]=$e.groups[1].value;};
            $line=$arr -join ',';
            $sw.WriteLine($line);
            $sw.Flush();
        };
    };
};
$sw.Close();
$fs.Close();COPY
1

评分人数

提供bat代写,为你省时省力省事,支付宝扫码头像支付
微信: unique2random

TOP

本帖最后由 lxh623 于 2020-7-7 15:06 编辑

回复 2# zaqmlp
请查收!
如果想得到下面的字段,怎么操作。谢谢!
<mapping type="PUA" cb:dec="983109">U+F0045</mapping>

TOP

本帖最后由 WHY 于 2020-6-27 13:41 编辑

Test.js
var srcDir = 'E:/Test/X42';  //存放xml的文件夹
var dstFile = 'result.csv';  //输出csv文件名
var out = [];  
var xml = new ActiveXObject('Microsoft.XMLDOM');
var fso = new ActiveXObject('Scripting.FileSystemObject');
var getXMLData = function(fp) {
    xml.load(fp);
    var reg = /<value>([^<>]*)</g;
    var arr = xml.selectNodes('//char'), Len = arr.length;
    for(var i=0; i<Len; i++){
        var s = arr[i].xml;
        var a = ['0', ['0', '0'], '0', '0'];
        var m = s.match(/<charName>([^<>]*)</);
        if(m) a[0] = '"' + m[1] + '"';
   
        var j = 0;
        while( m = reg.exec(s) ) a[1][j++] = '"' + m[1] + '"';
   
        var m = s.match(/[_"]unicode">([^<>]*)</);
        if(m) a[2] = '"' + m[1] + '"';
   
        var m = s.match(/"PUA">([^<>]*)</);
        if(m) a[3] = '"' + m[1] + '"';
        
        out.push( a.join(',') );
    }
}
var writeToCsv = function(dstFile) {
    var ado = new ActiveXObject('ADODB.Stream');
    ado.Mode = 3;
    ado.Type = 2;
    ado.Charset = 'utf-8';
    ado.Open();
    ado.WriteText(out.join('\r\n'));
    ado.SaveToFile(dstFile, 2);
}
var getXmlFile = function(fd){
    var e1 = new Enumerator(fso.getFolder(fd).Files);
    var e2 = new Enumerator(fso.getFolder(fd).SubFolders);
    for(; !e1.atEnd(); e1.moveNext()){
        var fp = e1.item().Path;
        if( !/\.xml$/i.test(fp) ) continue;
        getXMLData(fp);
    }
    for(; !e2.atEnd(); e2.moveNext())getXmlFile(e2.item().Path) ; //递归遍历子目录
}
getXmlFile(srcDir);
writeToCsv(dstFile);
WSH.Echo('Done');COPY
out.push(a) 效率非常低,改为 out.push(a.join(','))
贴一个不用正则的办法:
$srcDir = 'E:\Test\X42';
$dstFile = 'Result.CSV';
$fsw = New-Object System.IO.StreamWriter($dstFile, $false, [Text.Encoding]::UTF8);
$files = dir -Literal $srcDir -Filter '*.xml' -Recurse -File;
$count = $files.Count;
for($i=0; $i -lt $count; $i++) {
    [xml]$xml = [IO.File]::ReadAllLines($files[$i].FullName, [Text.Encoding]::UTF8);
    $node = $xml.GetElementsByTagName('char');
    $Len  = $node.Count;
    for($j=0; $j -lt $Len; $j++){
        $arr      = @('0', '0', '0', '0', '0');
        $charName = $node[$j].charName;
        $value    = @( $node[$j].charProp.Value );
        $type     = @( $node[$j].mapping.type );
        $text     = @( $node[$j].mapping.innerText );
        if( $charName -ne $null ) { $arr[0] = '"' + $charName + '"'; }
        for($k=0; $k -lt 2; $k++) {
            if( $value[$k] -ne $null ) { $arr[1+$k] = '"' + $value[$k] + '"'; }
            if( $type[$k] -ne $null ) {
                if( $type[$k].EndsWith('unicode') ){ $arr[3] = '"' + $text[$k] + '"'; }
                if( $type[$k] -eq 'PUA' ) { $arr[4] = '"' + $text[$k] + '"'; }
            }
        }
        $fsw.WriteLine( $arr -join  ',' );
    }
    if($i % 1000 -eq 0 ) { $fsw.Flush(); }
}
$fsw.Flush();
$fsw.Close();
pauseCOPY
1

评分人数

TOP

返回列表