Проблема с использованием Powershell для извлечения значения из структуры Json - PullRequest
0 голосов
/ 04 марта 2019

Используя Powershell, я получаю фрагмент json, возвращаемый в мою переменную First (это всегда работает нормально);

# Initialise variables...
$nMessage_id = "";
$whatStatusJsonContent = "";
# Function https://abc.googleapis.com/abc/load call here and returns...
$whatStatusJsonContent = '{"message_id":9093813071099257562}'

Затем я вызываю функцию convert в переменную temp, как здесь;

$ResponseBody = ConvertFrom-Json $whatStatusJsonContent;

, который помещает Json в симпатичную небольшую структуру данных, подобную этой;

         message_id
         ----------
9093813071099257562

Из которой я могу выбрать нужное значение, вызывая это;

$nMessage_id = $ResponseBody.message_id;

Обычно,это прекрасно работает, и я получаю значение во вторую переменную;

$nMessage_id = 9093813071099257562

Проблема в том, что иногда я ничего не получаю в $ nMessage_id , хотя $ whatStatusJsonContent определенно регистрируется как корректное возвращение Json из функции.

У меня такой вопрос: мне нужно ConvertFrom-Json или я могу прочитать его в необработанном виде из первой переменной ..?

КОМБИНИРОВАННОЕ РЕШЕНИЕ: благодаря @mklement () и @ Bernard-Moeskops

# Initialise variables...
$nMessage_id = "";
$whatStatusJsonContent = "";
# Function https://abc.googleapis.com/abc/load call here and returns...
$whatStatusJsonContent = '{"message_id":9093813071099257562}'

$ResponseBody = ConvertFrom-Json $whatStatusJsonContent;

if($ResponseBody.message_id){
    # ConvertFrom-Json got the value!
    $nMessage_id = $ResponseBody.message_id
}else{
    # ConvertFrom-Json didn't work!
    $nMessage_id = = ($whatStatusJsonContent -split '[:}]')[1]
}

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

В вашем коде нет ничего плохого.

ConvertFrom-Json должен работать как положено и возвращать экземпляр [pscustomobject] со свойством .message_id.

В вашем примере значение свойства message_id JSON представляет собой число , являющееся целым числом, для которого ConvertTo-Json автоматически выбирает подходящий целочисленный тип данных следующим образом: наименьший тип со знаком> = [int] (System.Int32) [1] , который может вместить значение ([int] -> [long] (System.Int64) -> [decimal] (System.Decimal));предостережение в том, что если значение не может даже вписаться в [decimal], используется - неточное - [double]. [2]

с примером JSON в вашем вопросе, [long] выбрано.

В последующем комментарии вы заявляете:

Подпрограмма совершает более 1000 вызовов / час, и для большинства из них Json возвращается и$nMessage_id получается отлично.Затем, внезапно, $nMessage_id становится пустым, хотя Json регистрируется как возвращающийся в порядке.Итак, где-то в ConvertFrom-Json или $ResponseBody.message_id значение пропадает ...

У меня нет объяснения, но если - по какой-то причине - ConvertFrom-Json является виновником, вы можете попробуйте манипулирование строкой в качестве временного решения , чтобы извлечь идентификатор сообщения и посмотреть, поможет ли это:

$whatStatusJsonContent = '{"message_id":9093813071099257562}'

# Extract the message_id property value as a *string*  
# (which you can cast to a numeric type if/as needed).  
$message_id = ($whatStatusJsonContent -split '[:}]')[1]

Выше хранится строкасодержание 9093813071099257562 в $message_id;обратите внимание, что, как написано, входная строка должна иметь точный формат, как указано выше в отношении пробелов;хотя анализ текста можно сделать более надежным, отсутствие необходимости беспокоиться о различиях в форматах является одной из веских причин для использования выделенного синтаксического анализатора, например ConvertFrom-Json.


Другой вариант - попробуйте другой JSON-анализатор , чтобы посмотреть, поможет ли это. Json.NET - это выдающийся анализатор JSON в мире .NET (который теперь лежит в основе командлетов JSON в PowerShell Core ):

$whatStatusJsonContent = '{"message_id":9093813071099257562}'

$message_id = [NewtonSoft.Json.Linq.JObject]::Parse($whatStatusJsonContent).message_id.Value

Примечание: Json.NET - как ConvetFrom-Json в PowerShell _Core - также рекомендуется использовать произвольно большой тип [bigint], если число слишком велико, чтобы поместиться в [long].

Использование сборки Json.NET имеетдобавленное преимущество лучшая производительность , чем командлет ConvertFrom-Json.

В PowerShell Core вы можете запустить приведенный выше код как есть (сборка предварительно загружена);в Windows PowerShell вам нужно будет загрузить пакет по приведенной выше ссылке и добавить сборку (NewtonSoft.Json.dll) в сеанс с помощью Add-Type -LiteralPath.


[1] Любопытно, что вPowerShell Core , начиная с (как минимум) v6.2.0, наименьший выбранный тип - [long] (System.Int64).

[2]PowerShell Core , начиная с (по крайней мере) v6.2.0, создает произвольно большой экземпляр [bigint] (System.Numerics.BigInteger), если значение больше не вписывается в [long];то есть тип [decimal] вообще пропускается.

0 голосов
/ 04 марта 2019

Вам придется преобразовать его, чтобы PowerShell мог его понять.Он преобразует строку в PSCustomObject.Просто проверьте, задав тип переменной до и после.

$ResponseBody.message_id.GetType()

Если иногда вывод ничего не значит, вы можете сделать что-то вроде:

if($ResponseBody.message_id){
    $nMessage_id = $ResponseBody.message_id
}else{
    throw "No message id found"
}

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...