当前位置: 首页 > 知识库问答 >
问题:

使用强势外壳分析具有变量类型的 XML 文件

孟绪
2023-03-14

我试图从脚本中删除变量的定义,并从XML配置文件中读取它们,如下所示:

XML文件

<?xml version="1.0" encoding="utf-8" ?>
<settings>
    <process>FALSE</process>
    <xmlDir>\\serv1\dev</xmlDir>
    <scanDir>\\serv1\dev</scanDir>
    <processedDir>\\serv1\dev\done</processedDir>
    <errorDir>\\serv1\dev\err</errorDir>
    <log>\\serv1\dev\log\dev-Log##DATE##.log</log>
    <retryDelay>5</retryDelay>
    <retryLimit>3</retryLimit>
</settings>

然后使用以下命令解析脚本中的 XML:

[xml]$configFile = Get-Content $PSScriptRoot\$confFile
$settings = $configFile.settings.ChildNodes
foreach ($setting in $settings) {  
    New-Variable -Name $setting.LocalName -Value ($setting.InnerText -replace '##DATE##',(get-date -f yyyy-MM-dd)) -Force
}

这很好,但问题是它们都是作为一个字符串读取的,但有些我需要一个整数。为了解决这个问题,我必须在创建变量后将它们改为整数,如下所示:

$retryDelay = ([int]$retryDelay)
$retryLimit = ([int]$retryLimit)

虽然这是可行的,但我希望在XML中包含其他变量,例如布尔值$true/$false(并作为布尔值读入),并且希望foreach能够处理它们的类型,而不是脚本中的其他行。任何线索都值得赞赏。

共有2个答案

宓博实
2023-03-14

我同意Tomalak的回答,JSON可能更适合您的用例。这里有一个实际示例向您展示如何使用它。这是使用从哈希表创建的自定义对象来生成JSON并将其保存到文件中:

$Config = [pscustomobject]@{
    Process = $false
    xmldir = '\\serv1\dev'
    scanDir = '\\serv1\dev'
    processedDir = '\\serv1\dev\done'
    errorDir = '\\serv1\dev\err'
    log = '\\serv1\dev\log\dev-Log##DATE##.log'
    retryDelay = 5
    retryLimit = 3
}

$Config | ConvertTo-Json | Out-File .\config.txt -Encoding UTF8

这会创建如下所示的JSON:

{
    "Process":  false,
    "xmldir":  "\\\\serv1\\dev",
    "scanDir":  "\\\\serv1\\dev",
    "processedDir":  "\\\\serv1\\dev\\done",
    "errorDir":  "\\\\serv1\\dev\\err",
    "log":  "\\\\serv1\\dev\\log\\dev-Log##DATE##.log",
    "retryDelay":  5,
    "retryLimit":  3
}

可以这样读:

$Settings = Get-Content .\config.txt -Encoding UTF8 | ConvertFrom-Json

由于您可以看到JSON存储变量的方式,PowerShell在读回变量时可以更好地正确键入变量。

简俊楚
2023-03-14

首先,永远不要像这样读取XML文件。这会破坏XML解析器中内置的编码检测,迟早会导致数据损坏。

# BAD, DO NOT USE
[xml]$configFile = Get-Content $PSScriptRoot\$confFile

正确读取XML文件的工作方式如下-创建一个新的XML对象,并让它处理文件加载:

$configFile = New-Object xml
$configFile.Load("$PSScriptRoot\$confFile")

其次,我强烈建议不要从文件中创建全局变量。这是一种糟糕的风格,因为盲目地覆盖现有的变量很容易破坏你的程序。使用散列来存储文件中的值,或者直接使用XML文件作为您的配置。

$config = @{}

foreach ($setting in $configFile.SelectNodes("/settings/*") ) {
    $config[$setting.Name] = $setting.InnerText
}

第三,XML 没有固有的数据类型信息。一切都是一个字符串,直到您添加有关它的更多信息。一种方法可以是类型属性(类型=“字符串可以被视为默认值):

<settings>
    <process type="boolean">FALSE</process>
    <xmlDir type="string">\\serv1\dev</xmlDir>
    <scanDir type="string">\\serv1\dev</scanDir>
    <processedDir type="string">\\serv1\dev\done</processedDir>
    <errorDir type="string">\\serv1\dev\err</errorDir>
    <log type="string">\\serv1\dev\log\dev-Log##DATE##.log</log>
    <retryDelay type="int">5</retryDelay>
    <retryLimit type="int">3</retryLimit>
</settings>

当然,type属性本身没有任何意义。您需要编写注意这些属性的代码,并进行必要的类型转换(if($setting.type-eq“boolean”){…}等)。

第四,我相信简单地使用JSON作为您的配置文件格式会更好。它更容易编辑,并且具有固有的数据类型信息。

{
    "settings": {
        "process": false,
        "xmlDir": "\\\\serv1\\dev",
        "scanDir": "\\\\serv1\\dev",
        "processedDir": "\\\\serv1\\dev\\done",
        "errorDir": "\\\\serv1\\dev\\err",
        "log": "\\\\serv1\dev\\log\\dev-Log##DATE##.log",
        "retryDelay": 5,
        "retryLimit": 3
    }
}

使用ConvertFrom-JSONcmdlet解析数据。使用Get-Content-Encode UTF8读取它。

在处理文本文件时,使用Encode参数很重要,在您使用Set-ContentOut-File编写文件时也很重要。这里没有隐藏的魔法可以做正确的事情,您必须明确编码。

以下是有关输出文件设置内容行为的更深入信息。Powershell设置属性和输出文件有什么区别?

 类似资料:
  • 本文向大家介绍Windows Powershell 变量的类型和强类型,包括了Windows Powershell 变量的类型和强类型的使用技巧和注意事项,需要的朋友参考一下 变量可以自动存储任何Powershell能够识别的类型信息,可以通过$variable的GetType().Name查看和验证Powershell分配给变量的数据类型。 会给数据分配一个最佳的数据类型;如果一个整数超出了32

  • 本文向大家介绍详细分析JavaScript变量类型,包括了详细分析JavaScript变量类型的使用技巧和注意事项,需要的朋友参考一下 变量类型                                  只有6种 : 四种原始数据类型boolean , number, string , undefine, 其他object,function是对象  typeof,instanceof  

  • 我正在Windows Server 2008r2上运行64位Powershell ISE。 调试时,我设置了一个变量,如下所示: 然后,我进行以下更改: 我再次单步执行脚本,即使调试器跨过修改后的行,当我将鼠标悬停在$dbName变量上时,它仍然显示值“db1”。我似乎唯一能解决这个问题的方法是重新启动ISE-这是一个痛苦! 有人能告诉我我哪里错了吗? *更新* 我在一个模块中有以下功能: 我有一

  • 我有基类WebAnswer, 和继承的类RequestAnsModel

  • 本文向大家介绍C语言变量类型的深入分析,包括了C语言变量类型的深入分析的使用技巧和注意事项,需要的朋友参考一下 C语言是强类型语言,定义变量时必须声明变量的类型,赋值的时候也只能是同种类型变量赋值。 一。变量的类型告诉编译器怎么处理这个变量的数据。          虽然c语言是强类型语言,但是不同类型的变量通过类型转换也可以赋值,甚至指针变量可以转化为int类型,转化为char类型。从本质上来说

  • 强制类型转换:将一个数据类型强制转换为其他的数据类型。 类型转换主要指,将其他的数据类型,转换为:String、Number、Boolean。你会把某个数据类型转换成 null 或者 undefined 吗?不会,因为这样做,没有意义。 其他的简单类型 --> String 方法一:变量 + "" 或者 变量 + "abc" 举例如下: var a = 123; // Number 类型 co