需要自动化一个脚本来search和replacehex的HEX到XML文件

简而言之,我们有一个访问控制服务器(A),每分钟将持卡人输出到一个XML文件中。

该文件需要导入到另一个访问控制服务器(B)。

服务器(A)导出的XML文件具有像这样的hex格式的所有卡号; DEC61810000000

我知道如何在Excel中实现转换,这里是一个例子;

  1. 我需要replace前8个字符,忽略最后六个零。

  2. 我需要从这个DEC61810到这个1018C6DE反转hex(请注意数字是如何保持成对,但切换位置)。

    • 在Excel中执行此操作的代码如下所示; =CONCATENATE(MID(C5,7,2),MID(C5,5,2),MID(C5,3,2),LEFT(C5,2))
  3. 现在,最后六位数字被剥离,hex是反转,我需要将1018C6DE转换为DEC,其中出来270059230

    • 在Excel中执行此操作的代码如下所示; =HEX2DEC(D5)

所以我的问题是,我不知道如何自动化这个过程,我不知道如何实现这个对XML文件。

环境是MS Windows 7 / Windows 2008,我不介意它是如何实现的,无论是电源shell,FART.exe或任何其他search和replace工具。

谢谢,史蒂夫

————————————————– —

感谢大家的帮助。 我能够用java脚本来满足特定的需求。

现在变得更有趣了。 一个新的要求是要求能够扭转数据从服务器(B)stream向服务器(A)的过程。 所以现在我需要扭转顺序。

它将从具有DEC版本的XML文件开始,并且转换后的文件将在末尾需要具有000000的HEX格式。

输出文件可以是一个普通的.txt文件,格式如下: (结束; 3; 1总是一样的)

 1;One;TestOne;E4583A4F000000;3;1 2;Two;TestTwo;9B2EB93F000000;3;1 

这是一个带有两(2)个持卡人条目的XML示例。

 <?xml version="1.0" encoding="utf-8" standalone="yes"?> <CrossFire culture-info="en-US" platform-version="0.0.640.0024" product-version="0.0.640.0025"> <SoftwareHouse.NextGen.Common.SecurityObjects.Personnel ImportMode="Default"> <FirstName>One</FirstName> <LastName>OneTest</LastName> <SoftwareHouse.NextGen.Common.SecurityObjects.PersonnelClearancePair ImportMode="Default"> <ClearanceKey>Clearance_1 [[Default]]</ClearanceKey> <PersonnelID>5000</PersonnelID> </SoftwareHouse.NextGen.Common.SecurityObjects.PersonnelClearancePair> <SoftwareHouse.NextGen.Common.SecurityObjects.Credential ImportMode="Default"> <CardNumber>1329223908</CardNumber> <Disabled>False</Disabled> </SoftwareHouse.NextGen.Common.SecurityObjects.Credential> </SoftwareHouse.NextGen.Common.SecurityObjects.Personnel> <SoftwareHouse.NextGen.Common.SecurityObjects.Personnel ImportMode="Default"> <FirstName>Two</FirstName> <LastName>TwoTest</LastName> <SoftwareHouse.NextGen.Common.SecurityObjects.PersonnelClearancePair ImportMode="Default"> <ClearanceKey>Clearance_1 [[Default]]</ClearanceKey> <PersonnelID>5001</PersonnelID> </SoftwareHouse.NextGen.Common.SecurityObjects.PersonnelClearancePair> <SoftwareHouse.NextGen.Common.SecurityObjects.Credential ImportMode="Default"> <CardNumber>1069100699</CardNumber> <Disabled>False</Disabled> </SoftwareHouse.NextGen.Common.SecurityObjects.Credential> </SoftwareHouse.NextGen.Common.SecurityObjects.Personnel> </CrossFire> 

这是一个PowerShell的解决scheme:

 function Get-AccessControlDecimal { param ( [string]$AccessControlHex ) # create an array to store the results $ac2=@() # loop around each pair of values adding to new array for($i=0; $i -lt $AccessControlHex.length; $i+=2){ $ac2+=$AccessControlHex[($i)..($i+1)] -join "" } # Reverse the order of the array [array]::Reverse($ac2) # Join the array back together $ac2 = $ac2 -join "" # convert to decimal [Convert]::ToInt32($ac2,16) } Get-AccessControlDecimal("DEC61810000000") 

更新1

下面是你的新需求的一个完整的解决scheme,我已经提供了一个函数去hex,并在循环中validation它们。

 # Read xml, would normally use get-content # [xml]$xml = Get-Content -Path $filename [xml]$xml = @" <?xml version="1.0" encoding="utf-8" standalone="yes"?> <CrossFire culture-info="en-US" platform-version="0.0.640.0024" product-version="0.0.640.0025"> <SoftwareHouse.NextGen.Common.SecurityObjects.Personnel ImportMode="Default"> <FirstName>One</FirstName> <LastName>OneTest</LastName> <SoftwareHouse.NextGen.Common.SecurityObjects.PersonnelClearancePair ImportMode="Default"> <ClearanceKey>Clearance_1 [[Default]]</ClearanceKey> <PersonnelID>5000</PersonnelID> </SoftwareHouse.NextGen.Common.SecurityObjects.PersonnelClearancePair> <SoftwareHouse.NextGen.Common.SecurityObjects.Credential ImportMode="Default"> <CardNumber>1329223908</CardNumber> <Disabled>False</Disabled> </SoftwareHouse.NextGen.Common.SecurityObjects.Credential> </SoftwareHouse.NextGen.Common.SecurityObjects.Personnel> <SoftwareHouse.NextGen.Common.SecurityObjects.Personnel ImportMode="Default"> <FirstName>Two</FirstName> <LastName>TwoTest</LastName> <SoftwareHouse.NextGen.Common.SecurityObjects.PersonnelClearancePair ImportMode="Default"> <ClearanceKey>Clearance_1 [[Default]]</ClearanceKey> <PersonnelID>5001</PersonnelID> </SoftwareHouse.NextGen.Common.SecurityObjects.PersonnelClearancePair> <SoftwareHouse.NextGen.Common.SecurityObjects.Credential ImportMode="Default"> <CardNumber>1069100699</CardNumber> <Disabled>False</Disabled> </SoftwareHouse.NextGen.Common.SecurityObjects.Credential> </SoftwareHouse.NextGen.Common.SecurityObjects.Personnel> </CrossFire> "@ function Get-ReversedArrary { param ( $accessControlCard ) # create an array to store the results $result=@() # loop around each pair of values adding to new array for($i=0; $i -lt $accessControlCard.length; $i+=2){ $result+=$accessControlCard[($i)..($i+1)] -join "" } # Reverse the order of the array [array]::Reverse($result) # Join the array back together $result -join "" } function Get-AccessControlDecimal { param ( [string]$AccessControlHex ) $reversed = Get-ReversedArrary($AccessControlHex) # convert to decimal [Convert]::ToInt32($reversed,16) } function Get-AccessControlHex { param ( [string]$AccessControlDecimal ) # convert to Hex $AccessControlHex = [Convert]::ToString($AccessControlDecimal,16) $AccessControlHex = Get-ReversedArrary($AccessControlHex) $AccessControlHex += "000000" $AccessControlHex } # loop around xml $i = 0 $crossfire = @() $xml.CrossFire."SoftwareHouse.NextGen.Common.SecurityObjects.Personnel" | %{ $i++ # $cardNumber = $_."SoftwareHouse.NextGen.Common.SecurityObjects.Credential".CardNUmber $cardNumberHex = Get-AccessControlHex($cardNumber) $cardNumberDec = Get-AccessControlDecimal($cardNumberHex) # Just for proving if ($cardNumber -ne $cardNumberDec) { Write-Error "Conversion to from hex failed!" } $o = @{ Id = $i Firstname = $_.FirstName LastName = $_.LastName CardNumberHex = $cardNumberHex Three = 3 One = 1 } $crossfire += New-Object PSObject -Property $o } # convert to csv, remove headers and quotes $crossfire | select Id, FirstName, LastName, CardNUmberHex, Three, One | ` ConvertTo-Csv -Delimiter ";" -NoTypeInformation | select -skip 1 | % {$_.Replace('"','')} 

如何使用JavaScript?

这将在input表格中find每8个数字的HEX字,随后是6个零,消除6个零,改变顺序并转换为十进制数。

 <html> <script> function convert() { var input = document.getElementById("input-text"); var words = input.value.split(/[ \t\n]/); var reg = new RegExp("[a-fA-F0-9]{8}000000"); for (var i=0;i<words.length; i++) { var word = words[i]; if(word.match(reg)) { // 8 digits HEX number with 6 zeros var v1,v2,v3,v4 v1 = word.substr(0,2); v2 = word.substr(2,2); v3 = word.substr(4,2); v4 = word.substr(6,2); word = v4+v3+v2+v1; words[i] = ""+parseInt(word, 16) } else { } } var output = ""; for (var i=0; i<words.length; i++) { output = output + words[i]+" "; } document.getElementById("output-text").value = output; } </script> <body> <textarea id="input-text"></textarea><br> <input value="convert" type="button" onclick="convert();"></input><br> <textarea id="output-text"></textarea><br> </body> </html> 

或者从http://nodejs.org/安装node.js

并创buildhex2dec.js文件

 function convert(input) { var words = input.split(/[ \t\n]/); var reg = new RegExp("[a-fA-F0-9]{8}000000"); for (var i=0;i<words.length; i++) { var word = words[i]; if(word.match(reg)) { // 8 digits HEX number with 6 zeros var v1,v2,v3,v4 v1 = word.substr(0,2); v2 = word.substr(2,2); v3 = word.substr(4,2); v4 = word.substr(6,2); word = v4+v3+v2+v1; words[i] = ""+parseInt(word, 16) } else { } } var output = ""; for (var i=0; i<words.length; i++) { output = output + words[i]+" "; } console.log(output); } process.stdin.on('readable', function(chunk) { var input = process.stdin.read(); if (input !== null) { convert(""+input); } }); 

节点hex2dec.js <inputfile>输出文件


对于你的第二个请求,你需要一个XMLparsing器

您可以轻松地为node.js安装xmlparsing器

https://github.com/Leonidas-from-XIV/node-xml2js

或进入

npm安装xml2js

然后制作如下的dec2hex.js文件。

 var xml2js = require('xml2js'); var parser = new xml2js.Parser(); process.stdin.on('readable', function(chunk) { var input = process.stdin.read(); if (input !== null) { parser.parseString(""+input, function(err,result){ //Extract the value from the data element var arr = (result.CrossFire["SoftwareHouse.NextGen.Common.SecurityObjects.Personnel"]); for(i=0;i<arr.length;i++) { var node = arr[i]; var firstName = node.FirstName[0]; var lastName = node.LastName[0]; var cardNumber = node["SoftwareHouse.NextGen.Common.SecurityObjects.Credential"][0].CardNumber[0]; var word = parseInt(cardNumber).toString(16); var v1,v2,v3,v4 v1 = word.substr(0,2); v2 = word.substr(2,2); v3 = word.substr(4,2); v4 = word.substr(6,2); word = v4+v3+v2+v1+"000000"; word = word.toUpperCase(); console.log((i+1)+";"+firstName+";"+lastName+";"+word+";3;1"); } }); } }); 

当一个32位的hex数转换成十进制时,有两种可能的解决scheme:如果高位是一个符号位(有符号数),结果在-2147483648和2147483647之间; 否则,当高位是数字(无符号数字)的一部分时,结果在0和4294967295之间。下面的批处理代码假设第一种情况:

 @echo off set input=%1 echo Input: %input% set /A output=0x%input:~6,2%%input:~4,2%%input:~2,2%%input:~0,2% echo Output: %output% 

输出示例:

 C:\> test DEC61810000000 Input: DEC61810000000 Output: 270059230 

如果需要,可以修改先前的代码以转换无符号的数字。

如果您向我们展示.XML文件的格式,也许我们可能会开发一个batch file,根据需要对其进行处理。


编辑添加新的请求的解决scheme

下面的batch file解决你的第二个请求,也就是说,它需要你的xml示例文件并产生请求的输出:

 @echo off setlocal EnableDelayedExpansion set hexa=0123456789ABCDEF set i=0 for /F "tokens=2,3 delims=<>" %%a in (input.txt) do ( if "%%a" equ "FirstName" ( set FirstName=%%b ) else if "%%a" equ "LastName" ( set LastName=%%b ) else if "%%a" equ "CardNumber" ( set CardNumber=%%b set "H=" for /L %%i in (1,1,8) do ( set /A "digit=CardNumber&0xF, CardNumber>>=4" for /F %%d in ("!digit!") do set "H=!H!!hexa:~%%d,1!" ) set /A i+=1 set CardHex=!H:~1,1!!H:~0,1!!H:~3,1!!H:~2,1!!H:~5,1!!H:~4,1!!H:~7,1!!H:~6,1! echo !i!;!FirstName!;!LastName!;!CardHex!000000;3;1 ) ) 

输出示例:

 C:\> test 1;One;OneTest;E4583A4F000000;3;1 2;Two;TwoTest;9B2EB93F000000;3;1 

以前的解决scheme可能很容易修改,以处理几个* .XML文件。

正如我之前所说,为了做你的第一个请求相同的事情,我们需要一个input文件和所需的输出的例子…