Я выполняю рефакторинг кода функции чтения XML на основе методов класса и вижу некоторые проблемы. С помощью этой функции я могу запустить тест и проверить правильность загруженного XML, затем изменить XML и проверить наличие ошибок. Но этот подход на основе классов терпит неудачу из-за того, что «файл открыт в другой программе», заставляя меня закрыть консоль, прежде чем я смогу пересмотреть XML. Первоначально я использовал путь непосредственно в xmlReader. Поэтому я перешел на вход StreamReader в xmlReader. И я даже поиграл с созданием нового xmlDocument и импортом корневого узла загруженного XML в этот новый xmlDocument. Ни один не работает. Я подозреваю, что причина работы версии, основанной на функции, заключается в том, что переменная xmlReader является локальной областью действия, поэтому она выходит из области действия после завершения функции. Но я цепляюсь за соломинку там. Я также читал, что сборка мусора может быть проблемой, поэтому я добавил [system.gc]::Collect()
сразу после удаления и все еще без изменений.
class ImportXML {
# Properties
[int]$status = 0
[xml.xmlDocument]$xml = ([xml.xmlDocument]::New())
[collections.arrayList]$message = ([collections.arrayList]::New())
# Methods
[xml.xmlDocument] ImportFile([string]$path) {
$importError = $false
$importFile = ([xml.xmlDocument]::New())
$xmlReaderSettings = [xml.xmlReaderSettings]::New()
$xmlReaderSettings.ignoreComments = $true
$xmlReaderSettings.closeInput = $true
$xmlReaderSettings.prohibitDtd = $false
try {
$streamReader = [io.streamReader]::New($path)
$xmlreader = [xml.xmlreader]::Create($streamReader, $xmlReaderSettings)
[void]$importFile.Load($xmlreader)
$xmlreader.Dispose
$streamReader.Dispose
} catch {
$exceptionName = $_.exception.GetType().name
$exceptionMessage = $_.exception.message
switch ($exceptionName) {
Default {
[void]$this.message.Add("E_$($exceptionName): $exceptionMessage")
$importError = $true
}
}
}
if ($importError) {
$importFile = $null
}
return $importFile
}
}
class SettingsXML : ImportXML {
# Constructor
SettingsXML([string]$path){
if ($this.xml = $this.ImportFile($path)) {
Write-Host "$path!"
} else {
Write-Host "$($this.message)"
}
}
}
$settingsPath = '\\Mac\iCloud Drive\Px Tools\Dev 4.0\Settings.xml'
$settings = [SettingsXML]::New($settingsPath)
РЕДАКТИРОВАТЬ: я также попытался FileStream, а не StreamReader, с FileShareReadWrite, вот так
$fileMode = [System.IO.FileMode]::Open
$fileAccess = [System.IO.FileAccess]::Read
$fileShare = [System.IO.FileShare]::ReadWrite
$fileStream = New-Object -TypeName System.IO.FileStream $path, $fileMode, $fileAccess, $fileShare
Все еще не повезло.