Использование ConvertFrom-String со значением, которое присутствует не во всех наборах данных - PullRequest
0 голосов
/ 10 января 2019

У меня есть текстовый файл с структурированными данными (аналогично Json), который я хочу проанализировать с помощью ConvertFrom-String для извлечения части данных. Я не могу изменить то, как данные структурированы в файле, поэтому мне приходится иметь дело с ними такими, какие они есть.

Вот пример данных. Полный файл содержит гораздо больше этих блоков, и каждый блок имеет больше «свойств», чем то, что я здесь показываю (оставляя его маленьким и читаемым :-)). Обратите внимание, что третий блок имеет свойство icon, которого нет у других элементов.

$Data = @'
    c_first_item = {    
        time = 270  
        category = cat_red
        min_value = {
            int = 10
        }
        max_value = {
            int = 20
        }
    }

    c_second_item = {   
        time = 270
        category = cat_blue
        min_value = {
            float = 10
        }
        max_value = {
            float = 20
        }
    }

    c_third_item = {    
        time = 270
        icon = c_third_icon
        category = cat_red
        min_value = {
            int = 10
        }
        max_value = {
            int = 20
        }
    }
'@

А вот мой шаблон, используемый ConvertFrom-String.

    $Template = @'
    {Name*:c_first_item} = \{   
        time = 270

        category = {Category:cat_red}


        random_property = \{
            random_property_value = 10
        \}

        random_property = \{
            random_property_value = 20
        \}
    \}

    {Name*:c_second_item} = \{
        time = 100
        icon = {Picture?:c_third_icon}

        category = {Category:cat_blue}

        random_property = \{
            random_property_value = 10
        \}

        random_property = \{
            random_property_value = 20
        \}
    \}
'@  

Я выполнял этот код с ConvertFrom-String для анализа нужных мне данных:

$Result = $Data | ConvertFrom-String -TemplateContent $Template

Ожидаемый результат должен был выглядеть так:

Name          Category  Picture
----          --------  -------
c_first_item  cat_red   
c_second_item cat_blue
c_third_item  cat_red   c_third_icon

Но вместо этого я получил это:

Name          Category
----          --------
c_first_item  cat_red   
c_second_item cat_blue
c_third_item  cat_red  

Как вы можете видеть, в моем выходном объекте нет свойства Picture, так как ConvertFrom-String не смог проанализировать данные в соответствии с тем, что я спросил. Я думаю, что примеры, которые я привожу, не достаточно хороши, чтобы научить алгоритму реакции.

Могу ли я научить ConvertFrom-String получить пустое свойство Picture для блоков, где icon не существует?


Обновление: 25 января

По запросу @iRon, вот пример, который добавляет свойство Length к результату.

Сначала файл, который я анализирую (Test.txt):

d_mem_towers_sulfuric_forest = {
    is_for_colonizeable = yes
    category = deposit_cat_rare

    icon = d_radioactive_wasteland

    resources = {
        category = planet_deposits
        produces = {
            society_research = 4
            energy = 4
        }
    }

    planet_modifier = {
        planet_jobs_energy_produces_mult = 0.10
        planet_jobs_society_research_produces_mult = 0.10
        planet_max_districts_add = -1
        pop_environment_tolerance = -0.15
    }

    drop_weight = {
        weight = 0
    }
}

Затем файл шаблона (Template.txt):

{Object*:{Name:d_mem_sadrell_capital} = \{
    is_for_colonizeable = yes
    category = {Category:deposit_cat_rare}

    icon = {Picture:d_building}

    planet_modifier = \{
        planet_housing_add = 3
        pop_environment_tolerance = 0.1
        planet_jobs_specialist_produces_mult = 0.15
    \}

    triggered_planet_modifier = \{
        potential = \{
            exists = owner
            owner = \{ is_regular_empire = yes \}
        \}
        modifier = \{
            job_researcher_add = 2
            job_clerk_add = 2
        \}
    \}

    triggered_planet_modifier = \{
        potential = \{
            exists = owner
            owner = \{ is_hive_empire = yes \}
        \}
        modifier = \{
            job_brain_drone_add = 2
            job_maintenance_drone_add = 2
        \}
    \}

    triggered_planet_modifier = \{
        potential = \{
            exists = owner
            owner = \{ is_machine_empire = yes \}
        \}
        modifier = \{   
            job_calculator_add = 2
            job_maintenance_drone_add = 2
        \}
    \}

    drop_weight = \{
        weight = 0
    \}
\}}

{Object*:{Name:d_mem_sadrell_industrial_complex} = \{
    is_for_colonizeable = yes
    category = {Category:deposit_cat_rare}

    icon = {Picture:d_crater}

    planet_modifier = \{
        pop_environment_tolerance = -0.1
        planet_jobs_minerals_produces_mult = 0.25
        district_mining_max = 4
    \}

    drop_weight = \{
        weight = 0
    \}
\}}

{Object*:{Name:_mem_strange_mountain} = \{
    time = 365
    is_for_colonizeable = yes
    category = {Category:deposit_cat_blockers}

    icon = {Picture:d_mem_strange_mountain}

    resources = \{
        category = deposit_blockers
        cost = \{
            energy = 1000
            minerals = 1000
        \}
    \}

    drop_weight = \{
        weight = 0
    \}
\}}

Наконец, вот фрагмент кода, который я использую для извлечения данных:

$testText = Get-Content  -Path "Path\to\text.txt" #MEM
$template = 'Path\to\template.txt'

$result = $testText |
    ConvertFrom-String -TemplateFile $template |
    Select-Object -ExpandProperty Object |
    Union-Object

$result

Ожидаемый результат должен быть таким:

Name                         Category         Picture               
----                         --------         -------        
d_mem_towers_sulfuric_forest deposit_cat_rare d_radioactive_wasteland

Но вместо этого я получаю:

Name                         Category         Picture                 Length
----                         --------         -------                 ------
d_mem_towers_sulfuric_forest deposit_cat_rare d_radioactive_wasteland
                                                                      0

В моем объекте есть вторая строка, содержащая свойство Length, которое я не анализирую, поэтому я предполагаю, что оно каким-то образом взято из Union-Object.

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 17 января 2019

После небольшой задержки вот ответ. Мне помог Николас Боден (https://www.linkedin.com/in/nicolas-baudin-63491a111/), чтобы найти его.

Проблема пришла из шаблона. Так как свойство icon существует не во всех наборах, функция столкнулась с трудностями при его получении и фактически не возвращала его вообще. Хитрость заключается в том, чтобы изменить шаблон, включив в него структуру, которая затем будет возвращена со всеми свойствами, включая Picture. Эта структура возвращается ConvertFrom-String как объект, все свойства которого являются значением, которое вы пытаетесь проанализировать.

Новый шаблон выглядит так:

$Template = @'
{Object:*{Name:c_first_item} = \{   
    time = 270

    category = {Category:cat_red}


    random_property = \{
        random_property_value = 10
    \}

    random_property = \{
        random_property_value = 20
    \}
\}}

{Object:*{Name:c_second_item} = \{
    time = 100
    icon = {Picture?:c_third_icon}

    category = {Category:cat_blue}

    random_property = \{
        random_property_value = 10
    \}

    random_property = \{
        random_property_value = 20
    \}
\}}
'@  

Сама команда была адаптирована для соответствия новому выведенному объекту, и теперь она имеет вид:

$Result = $Data | ConvertFrom-String -TemplateContent $Template |
                  Select-Object -ExpandProperty Object |
                  Union-Object

Как видите, я использую вашу функцию Union-Object, которая пригодится, поскольку у меня есть несколько шаблонов, которые не выводят одно и то же свойство для каждого объекта. Таким образом, у меня может быть одна функция для анализа всех моих файлов.

0 голосов
/ 11 января 2019

Хотя все ваши свойства (включая Picture) находятся в объекте $Result, они не будут выводиться (на дисплей), поскольку не все (особенно первые) объекты содержат свойство Picture (см., Относящиеся к Проблема: Не все свойства отображаются ):

PS C:\> $Result

Name          Category
----          --------
c_first_item  cat_red
c_second_item cat_blue
c_third_item  cat_red

Командлет Union-Object добавит все недостающие свойства (со значением $Null) к соответствующим объектам:

PS C:\> $Result = $Result | Union-Object
PS C:\> $Result

Name          Category Picture
----          -------- -------
c_first_item  cat_red
c_second_item cat_blue
c_third_item  cat_red
                       cat_blue
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...