Анализ вложенного JSON с ключом / значением на разных уровнях с использованием TypeScript в узле

#node.js #json #typescript #parsing

#node.js #json #typescript #разбор

Вопрос:

Я получил некоторые данные, которые мне нужно проанализировать на разных уровнях, чтобы извлечь их и сохранить аналогичную структуру в том виде, в котором она была сформирована. Я использую TypeScript в среде Node (Google Cloud), которую я использую для своего текущего проекта. Я совсем новичок в этом языке и среде, я использую рекомендации по аспекту языковых функций, а не по части обработки данных.

Данные, которые у меня есть в качестве входных данных, представлены в формате XML и представлены следующим образом:

 <item>
    <key xsi:type="xsd:string">intermedite_key</key>
    <value xsi:type="ns2:Map">
        <item>
            <key xsi:type="xsd:string">Key_parse_first_level_1</key>
            <value xsi:type="ns2:Map">
                <item>
                    <key xsi:type="xsd:string">intermedite_key</key>
                    <value xsi:type="ns2:Map">
                        <item>
                            <key xsi:type="xsd:string">Key_parse_second_level_1</key>
                            <value xsi:type="ns2:Map">
                                <item>
                                    <key xsi:type="xsd:int">intermedite_key</key>
                                    <value xsi:type="ns2:Map">
                                        <item>
                                            <key xsi:type="xsd:string">Key_1</key>
                                            <value xsi:type="xsd:string">DataToParse</value>
                                        </item>
                                        <item>
                                            <key xsi:type="xsd:string">Key_2</key>
                                            <value xsi:type="xsd:string">DataToParse</value>
                                        </item>
                                    </value>
                                </item>
                            </value>
                        </item>
                        <item>
                            <key xsi:type="xsd:string">Key_parse_second_level_2</key>
                            <value xsi:type="ns2:Map">
                                <item>
                                    <key xsi:type="xsd:int">intermedite_key</key>
                                    <value xsi:type="ns2:Map">
                                        <item>
                                            <key xsi:type="xsd:string">Key_parse_third_level_1</key>
                                            <value xsi:type="xsd:string">DataToFetch</value>
                                        </item>
                                        <item>
                                            <key xsi:type="xsd:string">Key_parse_third_level_2</key>
                                            <value xsi:type="xsd:string">DataToFetch</value>
                                        </item>
                                        </item>
                                    </value>
                                </item>
                            </value>
                        </item>
                    </value>
                </item>
            </value>
        </item>
        <item>
            <key xsi:type="xsd:string">Key_parse_first_level_2>
            <value xsi:type="ns2:Map">
                <item>
                    <key xsi:type="xsd:string">intermedite_key</key>
                    <value xsi:type="ns2:Map">
                        <item>
                            <key xsi:type="xsd:string">Key_parse_second_level_1</key>
                            <value xsi:type="ns2:Map">
                                <item>
                                    <key xsi:type="xsd:int">intermedite_key</key>
                                    <value xsi:type="ns2:Map">
                                        <item>
                                            <key xsi:type="xsd:string">Key_parse_third_level_1</key>
                                            <value xsi:type="xsd:string">DataToFetch</value>
                                        </item>
                                        <item>
                                            <key xsi:type="xsd:string">Key_parse_third_level_2</key>
                                            <value xsi:type="xsd:string">DataToFetch</value>
                                        </item>
                                    </value>
                                </item>
                            </value>
                        </item>
                    </value>
                </item>
            </value>
        </item>
        <item>
        
        ... Other items
        
        </item>
    </value>
</item>
  

Мне удалось написать этот фрагмент кода, который работает для анализа первого уровня, но на втором уровне:

 /*Converts the XMl into a an object with 'fast-xml-parser'*/
const getRawResponseJSON = parser.parse(XMLDataToConvert);

const FisrtLevel = getRawResponseJSON['item']['value']['item']

Object(FisrtLevel).forEach((FisrtLevelValues: any) => {

  const SecondLevel = Object.entries(FisrtLevelValues.value.item.value.item)

  SecondLevel.forEach((SecondLevelValues: any) => {

    console.log("value - "   SecondLevelValues);
    
    });
    
});
  

Это выходные данные консоли для Key_parse_second_level_1 :

 value - 0,[object Object] 

value - 1,[object Object] 
  

И для Key_parse_second_level_2:

 value - value,[object Object] 
  

Кажется, что значения Key_parse_second_level_1 не «выровнены» с Key_parse_second_level_2, и когда я углубляюсь, у меня нет ожидаемых результатов для ключей и значений. Поэтому у меня разные вопросы: было ли использование классов объектов хорошей идеей для этого случая (меня соблазнили использовать их для методов ключей и записей)? Было бы лучше использовать класс Array?

Ответ №1:

Я решил свою проблему, сделав это :

 const SecondLevel = Object.entries(FisrtLevelValues.value.item.value.item)

Object.keys(SecondLevel).forEach((SecondLevelKeys: any) => {

    let SecondLevelValues: any;
          
          if(String(SecondLevelKeys).match("value")){
  
            return;
  
          } else if (String(SecondLevelKeys).match("key")){
 
            SecondLevelValues = SecondLevel['value']['item']['value']['item'];
  
          } else if (String(SecondLevelKeys).match(/[0-9]/)) {
          

            SecondLevelValues = SecondLevel[SecondLevelKeys]['value']['item']['value']['item'];

          }

          Object.keys(SecondLevelValues).forEach((ThirdLevelKeys) => {
            
            const getKey = SecondLevelValues[ThirdLevelKeys]['key'];
            const getValues = SecondLevelValues[ThirdLevelKeys]['value'];

            ...

          });
    
});
  

На втором уровне if используется для фильтрации ключа «значение», потому что Object.key() дал два результата: «значение» и «ключ» (который является единственным, необходимым для моего дела). Последний else if фильтрует ключи по номеру, потому что при наличии нескольких элементов Object.key() давал мне номера в качестве индекса элемента.

На случай, если это кому-то поможет.