xml - 需要自动化脚本以在 XML 文件中搜索并将 HEX 替换为 DEC

标签 xml excel batch-file powershell

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

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

服务器(A)导出的XML文件中所有的卡号都是这样的HEX格式; DEC61810000000
我知道如何在 Excel 中实现转换,这里有一个例子;

  • 我需要替换前 8 个字符,忽略最后六个零。
  • 我需要从这个 DEC61810 反转 HEX对此1018C6DE (请注意数字是如何成对保存但位置不同的)。
  • 在 Excel 中执行此操作的代码如下; =CONCATENATE(MID(C5,7,2),MID(C5,5,2),MID(C5,3,2),LEFT(C5,2))
  • 现在最后六位数字被剥离,并且 HEX 被反转,我需要转换 1018C6DE到 DEC,结果为 270059230
  • 在 Excel 中执行此操作的代码如下;=HEX2DEC(D5)

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

    环境是 MS Windows 7/Windows 2008,我不介意它是如何实现的,无论是 power shell 、FART.exe 还是任何其他搜索和替换工具。

    谢谢,
    史蒂夫

    -------------------------------------------------- ---

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

    现在它变得更有趣了。一项新要求是要求能够逆转数据从服务器 (B) 流向服务器 (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解决方案:

    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

    这是针对您的新要求的完整解决方案,我提供了一个往返十六进制的函数,并在循环中验证了它们。
    # 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('"','')} 
    

    关于xml - 需要自动化脚本以在 XML 文件中搜索并将 HEX 替换为 DEC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22315224/

    相关文章:

    windows - 为什么我在 Windows 中的批处理文件不能连续执行?

    excel - 闪烁动画被 DoEvents 中断

    excel - 使用公式将 10 进制转换为 36 进制

    android - 如何去除透明 ActionBar 的标题背景?

    XML : tools for re-indenting XML in batch mode

    excel - 保护 Excel 工作表 - 不可能?

    batch-file - ffmpeg批处理脚本,将多个音频剪辑与一个图像组合在一起> mp4

    java - 如何在 Java 中停止等待输入的 Windows 批处理进程?

    java - 不同 Activity 中的元素不会折叠

    java - android:点击按钮时显示html页面?