0

假设我有以下格式的数据结构

https://docs.google.com/spreadsheets/d/e/2PACX-1vTFO_MoPwZmvKZOWT2J7kjGr9OC4uUb06zGxOdmXJ8h3FZ2Q0tpsoYH653Pm5mdNcM4Fs7KdlGWSkEy/pubhtml?gid=692973693&single=true

-----------
MovementOfGoods
---|  4.2. MovementOfGoods : N/A 
------|  4.2.1. NumberOfMovementLines : Inteiro *
------|  4.2.2. TotalQuantityIssued : Decimal *
------|  4.2.3. StockMovement : N/A 
---------|  4.2.3.1. DocumentNumber : Texto 60 *
---------|  4.2.3.2. ATCUD : Texto 100 *
---------|  4.2.3.3. DocumentStatus : N/A *
------------|  4.2.3.3.1. MovementStatus : Texto 1 *
------------|  4.2.3.3.2. MovementStatusDate : Data e Hora *
------------|  4.2.3.3.3. Reason : Texto 50 
------------|  4.2.3.3.4. SourceID : Texto 30 *
------------|  4.2.3.3.5. SourceBilling : Texto 1 *
---------|  4.2.3.4. Hash : Texto 172 *
---------|  4.2.3.5. HashControl : Texto 70 *
---------|  4.2.3.6. Period : Inteiro 
---------|  4.2.3.7. MovementDate : Data *
---------|  4.2.3.8. MovementType : Texto 2 *
---------|  4.2.3.9. SystemEntryDate : Data e Hora *
---------|  4.2.3.10. TransactionID : Texto 70 **
---------|  4.2.3.11. CustomerID : Texto 30 **
---------|  4.2.3.12. SupplierID : Texto 30 **
---------|  4.2.3.13. SourceID : Texto 30 *
---------|  4.2.3.14. EACCode : Texto 5 
---------|  4.2.3.15. MovementComments : Texto 60 
---------|  4.2.3.16. ShipTo : N/A 
------------|  4.2.3.16.1. DeliveryID : Texto 255 
------------|  4.2.3.16.2. DeliveryDate : Data 
------------|  4.2.3.16.3. WarehouseID : Texto 50 
------------|  4.2.3.16.4. LocationID : Texto 30 
------------|  4.2.3.16.5. Address : N/A 
---------------|  4.2.3.16.5.1. BuildingNumber : Texto 10 
---------------|  4.2.3.16.5.2. StreetName : Texto 200 
---------------|  4.2.3.16.5.3. AddressDetail : Texto 210 *
---------------|  4.2.3.16.5.4. City : Texto 50 *
---------------|  4.2.3.16.5.5. PostalCode : Texto 20 *
---------------|  4.2.3.16.5.6. Region : Texto 50 
---------------|  4.2.3.16.5.7. Country : Texto 2 *
---------|  4.2.3.17. ShipFrom : N/A 
------------|  4.2.3.17.1. DeliveryID : Texto 255 
------------|  4.2.3.17.2. DeliveryDate : Data 
------------|  4.2.3.17.3. WarehouseID : Texto 50 
------------|  4.2.3.17.4. LocationID : Texto 30 
------------|  4.2.3.17.5. Address : N/A 
---------------|  4.2.3.17.5.1. BuildingNumber : Texto 10 
---------------|  4.2.3.17.5.2. StreetName : Texto 200 
---------------|  4.2.3.17.5.3. AddressDetail : Texto 210 *
---------------|  4.2.3.17.5.4. City : Texto 50 *
---------------|  4.2.3.17.5.5. PostalCode : Texto 20 *
---------------|  4.2.3.17.5.6. Region : Texto 20 
---------------|  4.2.3.17.5.7. Country : Texto 2 *
---------|  4.2.3.18. MovementEndTime : Data e hora 
---------|  4.2.3.19. MovementStartTime : Data e hora *
---------|  4.2.3.20. ATDocCodeID : Texto 200 
---------|  4.2.3.21. Line : N/A *
------------|  4.2.3.21.1. LineNumber : Inteiro *
------------|  4.2.3.21.2. OrderReferences : N/A 
---------------|  4.2.3.21.2.1. OriginatingON : Texto 60 
---------------|  4.2.3.21.2.2. OrderDate : Data 
------------|  4.2.3.21.3. ProductCode : Texto 60 *
------------|  4.2.3.21.4. ProductDescription : Texto 200 *
------------|  4.2.3.21.5. Quantity : Decimal *
------------|  4.2.3.21.6. UnitOfMeasure : Texto 20 *
------------|  4.2.3.21.7. UnitPrice : Monetário *
------------|  4.2.3.21.8. Description : Texto 200 *
------------|  4.2.3.21.9. ProductSerialNumber : N/A 
---------------|  4.2.3.21.9.1. SerialNumber : Texto 100 *
------------|  4.2.3.21.10. DebitAmount : Monetário **
------------|  4.2.3.21.11. CreditAmount : Monetário **
------------|  4.2.3.21.12. Tax : N/A **
---------------|  4.2.3.21.12.1. TaxType : Texto 3 *
---------------|  4.2.3.21.12.2. TaxCountryRegion : Texto 5 *
---------------|  4.2.3.21.12.3. TaxCode : Texto 10 *
---------------|  4.2.3.21.12.4. TaxPercentage : Decimal *
------------|  4.2.3.21.13. TaxExemptionReason : Texto 60 **
------------|  4.2.3.21.14. TaxExemptionCode : Texto 3 **
------------|  4.2.3.21.15. SettlementAmount : Monetário 
------------|  4.2.3.21.16. CustomsInformation : N/A 
---------------|  4.2.3.21.16.1. ARCNo : Texto 21 
---------------|  4.2.3.21.16.2. IECAmount : Monetário 
---------|  4.2.3.22. DocumentTotals : N/A *
------------|  4.2.3.22.1. TaxPayable : Monetário *
------------|  4.2.3.22.2. NetTotal : Monetário *
------------|  4.2.3.22.3. GrossTotal : Monetário *
------------|  4.2.3.22.4. Currency : N/A 
---------------|  4.2.3.22.4.1. CurrencyCode : Texto 3 *
---------------|  4.2.3.22.4.2. CurrencyAmount : Monetário *
---------------|  4.2.3.22.4.3. ExchangeRate : Decimal *

[Embedded structures]
~> MovementOfGoods
~> StockMovement
~> DocumentStatus
~> ShipTo
~> Address
~> ShipFrom
~> Address
~> Line
~> OrderReferences
~> ProductSerialNumber
~> Tax
~> CustomsInformation
~> DocumentTotals
~> Currency

我想将其解析为嵌入了对象的 JSON,以便遵循编号创建的层次结构。

以上是从 Google Sheets 导出的一个 tsv 文件的解析版本, https ://docs.google.com/spreadsheets/d/e/2PACX-1vTFO_MoPwZmvKZOWT2J7kjGr9OC4uUb06zGxOdmXJ8h3FZ2Q0tpsoYH653Pm5mdNcM4Fs7KdlGWSkEy/pubxhtml?gid=69279

我想这样做的算法需要知道每行的“级别”是什么,当一个新的缩进即将被制作成一个新的对象时,更新的甚至嵌入其中的对象,然后回到根目录,如在

-----------
Customer
---|  2.2.1. CustomerID : Texto 30 *
---|  2.2.2. AccountID : Texto 30 *
---|  2.2.3. CustomerTaxID : Texto 30 *
---|  2.2.4. CompanyName : Texto 100 *
---|  2.2.5. Contact : Texto 50 
---|  2.2.6. BillingAddress : N/A *
------|  2.2.6.1. BuildingNumber : Texto 10 
------|  2.2.6.2. StreetName : Texto 200 
------|  2.2.6.3. AddressDetail : Texto 210 *
------|  2.2.6.4. City : Texto 50 *
------|  2.2.6.5. PostalCode : Texto 20 *
------|  2.2.6.6. Region : Texto 50 
------|  2.2.6.7. Country : Texto 12 *
---|  2.2.7. ShipToAddress : N/A 
------|  2.2.7.1. BuildingNumber : Texto 10 
------|  2.2.7.2. StreetName : Texto 200 
------|  2.2.7.3. AddressDetail : Texto 210 *
------|  2.2.7.4. City : Texto 50 *
------|  2.2.7.5. PostalCode : Texto 20 *
------|  2.2.7.6. Region : Texto 50 
------|  2.2.7.7. Country : Texto 12 *
---|  2.2.8. Telephone : Texto 20 
---|  2.2.9. Fax : Texto 20 
---|  2.2.10. Email : Texto 60 
---|  2.2.11. Website : Texto 60 
---|  2.2.12. SelfBillingIndicator : Inteiro *

[Embedded structures]
~> BillingAddress
~> ShipToAddress

例如。

我当前的代码遍历列表并检测哪些是嵌入式结构,但无法跟踪应该嵌入哪些结构,因此层次结构丢失了,或者实际上只是视觉的。在浏览每张纸之后,列出了“[嵌入式结构]”,但都是扁平的,而不是在树中。

var request = require('request')

url = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTFO_MoPwZmvKZOWT2J7kjGr9OC4uUb06zGxOdmXJ8h3FZ2Q0tpsoYH653Pm5mdNcM4Fs7KdlGWSkEy/pub?gid=692973693&single=true&output=tsv"

request(url, function (error, response, body) {
  if (body != undefined) {

    let lines = body.split('\r')
    let lastLevel = 0
    let dataStructs = [];

    lines.forEach(function(line, index) {
      if (index != 0) {
        columns = line.split('\t')
        let currentLevel = (columns[0].trim().split(".").length - 1)
        if (index == 1) {
          initialLevel = currentLevel;
        }
        if (columns[5].toLowerCase() == 'n/a') dataStructs.push(columns[2]);
        if (currentLevel !== lastLevel) {
          if (currentLevel > lastLevel) {
            console.log(columns[0].trim(), columns[2].trim(), ':', columns[5].trim(), columns[1].trim())
          } else if (currentLevel < lastLevel) {
            console.log(columns[0].trim(), columns[2].trim(), ':', columns[5].trim(), columns[1].trim())
          }
          lastLevel = currentLevel
        } else {
          console.log(columns[0].trim(), columns[2].trim(), ':', columns[5].trim(), columns[1].trim())
        }
      }
    });
    console.log('\n[Embedded structures]')
    dataStructs.forEach(struct => {
      console.log('~>', struct/* , '=', modelName+struct, '?' */)
    })
    console.log('\n')
  }
})

上面的代码将输出

4.2. MovementOfGoods : N/A 
4.2.1. NumberOfMovementLines : Inteiro *
4.2.2. TotalQuantityIssued : Decimal *
4.2.3. StockMovement : N/A 
4.2.3.1. DocumentNumber : Texto 60 *
4.2.3.2. ATCUD : Texto 100 *
4.2.3.3. DocumentStatus : N/A *
4.2.3.3.1. MovementStatus : Texto 1 *
4.2.3.3.2. MovementStatusDate : Data e Hora *
4.2.3.3.3. Reason : Texto 50 
4.2.3.3.4. SourceID : Texto 30 *
4.2.3.3.5. SourceBilling : Texto 1 *
4.2.3.4. Hash : Texto 172 *
4.2.3.5. HashControl : Texto 70 *
4.2.3.6. Period : Inteiro 
4.2.3.7. MovementDate : Data *
4.2.3.8. MovementType : Texto 2 *
4.2.3.9. SystemEntryDate : Data e Hora *
4.2.3.10. TransactionID : Texto 70 **
4.2.3.11. CustomerID : Texto 30 **
4.2.3.12. SupplierID : Texto 30 **
4.2.3.13. SourceID : Texto 30 *
4.2.3.14. EACCode : Texto 5 
4.2.3.15. MovementComments : Texto 60 
4.2.3.16. ShipTo : N/A 
4.2.3.16.1. DeliveryID : Texto 255 
4.2.3.16.2. DeliveryDate : Data 
4.2.3.16.3. WarehouseID : Texto 50 
4.2.3.16.4. LocationID : Texto 30 
4.2.3.16.5. Address : N/A 
4.2.3.16.5.1. BuildingNumber : Texto 10 
4.2.3.16.5.2. StreetName : Texto 200 
4.2.3.16.5.3. AddressDetail : Texto 210 *
4.2.3.16.5.4. City : Texto 50 *
4.2.3.16.5.5. PostalCode : Texto 20 *
4.2.3.16.5.6. Region : Texto 50 
4.2.3.16.5.7. Country : Texto 2 *
4.2.3.17. ShipFrom : N/A 
4.2.3.17.1. DeliveryID : Texto 255 
4.2.3.17.2. DeliveryDate : Data 
4.2.3.17.3. WarehouseID : Texto 50 
4.2.3.17.4. LocationID : Texto 30 
4.2.3.17.5. Address : N/A 
4.2.3.17.5.1. BuildingNumber : Texto 10 
4.2.3.17.5.2. StreetName : Texto 200 
4.2.3.17.5.3. AddressDetail : Texto 210 *
4.2.3.17.5.4. City : Texto 50 *
4.2.3.17.5.5. PostalCode : Texto 20 *
4.2.3.17.5.6. Region : Texto 20 
4.2.3.17.5.7. Country : Texto 2 *
4.2.3.18. MovementEndTime : Data e hora 
4.2.3.19. MovementStartTime : Data e hora *
4.2.3.20. ATDocCodeID : Texto 200 
4.2.3.21. Line : N/A *
4.2.3.21.1. LineNumber : Inteiro *
4.2.3.21.2. OrderReferences : N/A 
4.2.3.21.2.1. OriginatingON : Texto 60 
4.2.3.21.2.2. OrderDate : Data 
4.2.3.21.3. ProductCode : Texto 60 *
4.2.3.21.4. ProductDescription : Texto 200 *
4.2.3.21.5. Quantity : Decimal *
4.2.3.21.6. UnitOfMeasure : Texto 20 *
4.2.3.21.7. UnitPrice : Monetário *
4.2.3.21.8. Description : Texto 200 *
4.2.3.21.9. ProductSerialNumber : N/A 
4.2.3.21.9.1. SerialNumber : Texto 100 *
4.2.3.21.10. DebitAmount : Monetário **
4.2.3.21.11. CreditAmount : Monetário **
4.2.3.21.12. Tax : N/A **
4.2.3.21.12.1. TaxType : Texto 3 *
4.2.3.21.12.2. TaxCountryRegion : Texto 5 *
4.2.3.21.12.3. TaxCode : Texto 10 *
4.2.3.21.12.4. TaxPercentage : Decimal *
4.2.3.21.13. TaxExemptionReason : Texto 60 **
4.2.3.21.14. TaxExemptionCode : Texto 3 **
4.2.3.21.15. SettlementAmount : Monetário 
4.2.3.21.16. CustomsInformation : N/A 
4.2.3.21.16.1. ARCNo : Texto 21 
4.2.3.21.16.2. IECAmount : Monetário 
4.2.3.22. DocumentTotals : N/A *
4.2.3.22.1. TaxPayable : Monetário *
4.2.3.22.2. NetTotal : Monetário *
4.2.3.22.3. GrossTotal : Monetário *
4.2.3.22.4. Currency : N/A 
4.2.3.22.4.1. CurrencyCode : Texto 3 *
4.2.3.22.4.2. CurrencyAmount : Monetário *
4.2.3.22.4.3. ExchangeRate : Decimal *

[Embedded structures]
~> MovementOfGoods
~> StockMovement
~> DocumentStatus
~> ShipTo
~> Address
~> ShipFrom
~> Address
~> Line
~> OrderReferences
~> ProductSerialNumber
~> Tax
~> CustomsInformation
~> DocumentTotals
~> Currency

如何以树状形式查看这些列表并将字段/属性添加到正确的嵌入对象或对象的根?

编辑:

以上面的“客户”为例,使用表格结构,例如https://docs.google.com/spreadsheets/d/e/2PACX-1vTFO_MoPwZmvKZOWT2J7kjGr9OC4uUb06zGxOdmXJ8h3FZ2Q0tpsoYH653Pm5mdNcM4Fs7KdlGWSkEy/pubhtml?gid=700343

{
	"Customer": {
		"2.2.1. CustomerID": "Texto 30 *",
		"2.2.2. AccountID": "Texto 30 *",
		"2.2.3. CustomerTaxID": "Texto 30 *",
		"2.2.4. CompanyName": "Texto 100 *",
		"2.2.5. Contact": "Texto 50",
		"2.2.6. BillingAddress": {
			"2.2.6.1. BuildingNumber": "Texto 10",
			"2.2.6.2. StreetName": "Texto 200",
			"2.2.6.3. AddressDetail": "Texto 210 *",
			"2.2.6.4. City": "Texto 50 *",
			"2.2.6.5. PostalCode": "Texto 20 *",
			"2.2.6.6. Region": "Texto 50 ",
			"2.2.6.7. Country": "Texto 12 *"
		},
		"2.2.7. ShipToAddress": {
			"2.2.7.1. BuildingNumber": "Texto 10",
			"2.2.7.2. StreetName": "Texto 200",
			"2.2.7.3. AddressDetail": "Texto 210 *",
			"2.2.7.4. City": "Texto 50 *",
			"2.2.7.5. PostalCode": "Texto 20 *",
			"2.2.7.6. Region": "Texto 50",
			"2.2.7.7. Country": "Texto 12 *"
		},
		"2.2.8. Telephone ": "Texto 20",
		"2.2.9. Fax": "Texto 20",
		"2.2.10. Email": "Texto 60",
		"2.2.11. Website": "Texto 60",
		"2.2.12. SelfBillingIndicator": "Inteiro *"
	}
}

编辑2:要清楚,所需的“结果”是能够检测嵌套对象何时开始和结束,以及根据源表将它们嵌套在正确的位置。表中传递给 JSON 的特定列可能会有所不同,并且实际使用的语法也会从 JSON 更改为例如 rails 生成器。我缺少的是代码的“级别检测”部分。

编辑3:

var request = require('request')

url = "https://docs.google.com/spreadsheets/d/e/2PACX-1vTFO_MoPwZmvKZOWT2J7kjGr9OC4uUb06zGxOdmXJ8h3FZ2Q0tpsoYH653Pm5mdNcM4Fs7KdlGWSkEy/pub?gid=700343422&single=true&output=tsv"

request(url, function (error, response, body) {
  if (body != undefined) {

    let lines = body.split('\r')
    let lastLevel = 0
    let dataStructs = [];
    goneUpCounter = 0;
    console.log("{")

    lines.forEach(function (line, index) {
      if (index != 0) {
        columns = line.split('\t')
        let currentLevel = (columns[0].trim().split(".").length - 1)

        if (columns[5].toLowerCase() == 'n/a') {
          dataStructs.push(columns[2]);
          goneUpCounter += 1;
        }
        if (currentLevel !== lastLevel) {
          if (currentLevel > lastLevel) {
            if (columns[5].toLowerCase() == 'n/a') {
              console.log("{\"" + columns[2].trim() + "\" : {")
            } else {
              console.log("\"" + columns[0].trim(), columns[2].trim() + "\"", ':', "\"" + columns[5].trim(), columns[1].trim() + "\",")
            }
          } else if (currentLevel < lastLevel) {
            if (columns[5].toLowerCase() == 'n/a') {
              console.log("\"" + columns[2].trim() + "\" : {")
            } else {
              console.log("\"" + columns[0].trim(), columns[2].trim() + "\"", ':', "\"" + columns[5].trim(), columns[1].trim() + "\",")
            }
          }
          lastLevel = currentLevel
        } else {

          if (columns[5].toLowerCase() == 'n/a') {
            console.log("\"" + columns[2].trim() + "\" : {")
          } else {
            if ((lines[index + 1] != undefined && lines[index + 1].split('\t')[0].trim().split('.').length - 1 < lastLevel) || index + 1 == lines.length) {
              console.log("\"" + columns[0].trim(), columns[2].trim() + "\"", ':', "\"" + columns[5].trim(), columns[1].trim() + "\"")
            } else {
              console.log("\"" + columns[0].trim(), columns[2].trim() + "\"", ':', "\"" + columns[5].trim(), columns[1].trim() + "\",")
            }
          }

          if (lines[index + 1] != undefined && lines[index + 1].split('\t')[0].trim().split('.').length - 1 < lastLevel) {
            goneUpCounter -= 1;
            console.log('},')
          }
        }
      }
    });
    for (let i = 0; i < goneUpCounter + 1; i++) {
      console.log('}')
    }
  }
})

返回有效的 JSON,但代码很糟糕。

{
	"2.2.1. CustomerID": "Texto 30 *",
	"2.2.2. AccountID": "Texto 30 *",
	"2.2.3. CustomerTaxID": "Texto 30 *",
	"2.2.4. CompanyName": "Texto 100 *",
	"2.2.5. Contact": "Texto 50 ",
	"BillingAddress": {
		"2.2.6.1. BuildingNumber": "Texto 10 ",
		"2.2.6.2. StreetName": "Texto 200 ",
		"2.2.6.3. AddressDetail": "Texto 210 *",
		"2.2.6.4. City": "Texto 50 *",
		"2.2.6.5. PostalCode": "Texto 20 *",
		"2.2.6.6. Region": "Texto 50 ",
		"2.2.6.7. Country": "Texto 12 *"
	},
	"ShipToAddress": {
		"2.2.7.1. BuildingNumber": "Texto 10 ",
		"2.2.7.2. StreetName": "Texto 200 ",
		"2.2.7.3. AddressDetail": "Texto 210 *",
		"2.2.7.4. City": "Texto 50 *",
		"2.2.7.5. PostalCode": "Texto 20 *",
		"2.2.7.6. Region": "Texto 50 ",
		"2.2.7.7. Country": "Texto 12 *"
	},
	"2.2.8. Telephone": "Texto 20 ",
	"2.2.9. Fax": "Texto 20 ",
	"2.2.10. Email": "Texto 60 ",
	"2.2.11. Website": "Texto 60 ",
	"2.2.12. SelfBillingIndicator": "Inteiro *"
}

4

0 回答 0