cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Want the oppurtunity to discuss enhancements to PTC products? Join a working group! X

How to parse xml with custom tag from properties

Egor.Litvinov
10-Marble

How to parse xml with custom tag from properties

Эй! На данный момент я помещаю XML в свойства созданной вещи. XML выглядит следующим образом:

 

 

<?xml version="1.0" encoding="utf-8"?><n0:MT_ProductionFact xmlns:n0="content" xmlns:prx="content">
<n0:SendTimestamp>content</n0:SendTimestamp>
<n0:ContractProductions>
	<n0:ContractProduction>
		<n0:DeliveryNumber>content</n0:DeliveryNumber>
		<n0:DeliveryItemNumber>content</n0:DeliveryItemNumber>
		<n0:DeliveryMaterialNumber>000000005700000191</n0:DeliveryMaterialNumber>
		<n0:DeliveryMaterialShortName>content</n0:DeliveryMaterialShortName>
		<n0:DeliveryUnits>content</n0:DeliveryUnits>
		<n0:InboundDeliveryDocumentNumber>content</n0:InboundDeliveryDocumentNumber>
		<n0:InboundDeliveryItemNumber>content</n0:InboundDeliveryItemNumber>
		<n0:SupplierBatchCode>content</n0:SupplierBatchCode>
		<n0:DeliveryPlanDate>content</n0:DeliveryPlanDate>
		<n0:DeliveryPlanAmount>content</n0:DeliveryPlanAmount>
		<n0:MaterialDocumentNumber>content</n0:MaterialDocumentNumber>
		<n0:AccountingEntryDate>content</n0:AccountingEntryDate>
		<n0:StockAmountReceived>content</n0:StockAmountReceived>
		<n0:TargetAccountingChangeDate>content</n0:TargetAccountingChangeDate>
	</n0:ContractProduction>
	<n0:ContractProduction>
		<n0:DeliveryNumber>content</n0:DeliveryNumber>
		<n0:DeliveryItemNumber>content</n0:DeliveryItemNumber>
		<n0:DeliveryMaterialNumber>content</n0:DeliveryMaterialNumber>
		<n0:DeliveryMaterialShortName>content</n0:DeliveryMaterialShortName>
		<n0:DeliveryUnits>content</n0:DeliveryUnits>
		<n0:InboundDeliveryDocumentNumber>content</n0:InboundDeliveryDocumentNumber>
		<n0:InboundDeliveryItemNumber>content</n0:InboundDeliveryItemNumber>
		<n0:SupplierBatchCode>content</n0:SupplierBatchCode>
		<n0:DeliveryPlanDate>content</n0:DeliveryPlanDate>
		<n0:DeliveryPlanAmount>content</n0:DeliveryPlanAmount>
		<n0:MaterialDocumentNumber>content</n0:MaterialDocumentNumber>
		<n0:AccountingEntryDate>content</n0:AccountingEntryDate>
		<n0:StockAmountReceived>content</n0:StockAmountReceived>
		<n0:TargetAccountingChangeDate>content</n0:TargetAccountingChangeDate>
	</n0:ContractProduction>
</n0:ContractProductions>
</n0:MT_ProductionFact>

 

 

Но я не могу понять, как анализировать XML и помещать значения в таблицу. Все, что я нашел на форумах, не помогло. Может быть, вы можете мне помочь?

ACCEPTED SOLUTION

Accepted Solutions

I finally managed to find a solution. On the forum, I found a service for converting XML to JSON, and then I folded the JSON object into an infotable. Thanks for the help @VladimirRosu 

 

// result: JSON
let getJSON = me.ConvertXmlToJSON({
	xml: inputData /* XML */
});

// CreateInfoTableFromDataShape(infoTableName:STRING("InfoTable"), dataShapeName:STRING):INFOTABLE(Valenta.ProductionPlan)
let infoTable = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape({
	infoTableName: "InfoTable",
	dataShapeName: "Valenta.ProductionPlan"
});

for (let i = 0; i < getJSON.ContractProductions.ContractProduction.length; i++) {
	infoTable.AddRow({
		DeliveryNumber: getJSON.ContractProductions.ContractProduction[i].DeliveryNumber,
		DeliveryItemNumber: getJSON.ContractProductions.ContractProduction[i].DeliveryItemNumber,
		DeliveryMaterialNumber: getJSON.ContractProductions.ContractProduction[i].DeliveryMaterialNumber,
		DeliveryMaterialShortName: getJSON.ContractProductions.ContractProduction[i].DeliveryMaterialShortName,
		DeliveryUnits: getJSON.ContractProductions.ContractProduction[i].DeliveryUnits,
		InboundDeliveryDocumentNumber: getJSON.ContractProductions.ContractProduction[i].InboundDeliveryDocumentNumber,
		InboundDeliveryItemNumber: getJSON.ContractProductions.ContractProduction[i].InboundDeliveryItemNumber,
		SupplierBatchCode: getJSON.ContractProductions.ContractProduction[i].SupplierBatchCode,
		DeliveryPlanDate: getJSON.ContractProductions.ContractProduction[i].DeliveryPlanDate,
		DeliveryPlanAmount: getJSON.ContractProductions.ContractProduction[i].DeliveryPlanAmount,
		MaterialDocumentNumber: getJSON.ContractProductions.ContractProduction[i].MaterialDocumentNumber,
		AccountingEntryDate: getJSON.ContractProductions.ContractProduction[i].AccountingEntryDate,
		StockAmountReceived: getJSON.ContractProductions.ContractProduction[i].StockAmountReceived,
		TargetAccountingChangeDate: getJSON.ContractProductions.ContractProduction[i].TargetAccountingChangeDate
	});
}

let result = infoTable;

 

 

View solution in original post

10 REPLIES 10

If i use this code: 

let xml = me.data;
let newXML = new XML(xml);

I get only "SendTimeStamp"

Apparently, the duck method worked...

Now I have discovered that I get only this value in the "data" property...

What can I do wrong? Using the Put method, I send the file that I attached above, but I only get the string "<n0:SendTimestamp xmlns:n0="content">content</n0:SendTimestamp>"

please try steps in below article.

https://www.ptc.com/en/support/article/cs218242

It looks like a very old version. Doesn't the platform itself know how to parse an xml file into a table? If he still can't, I don't understand how to get to the data lying in the ContractProduction. I corrected the receipt of the XML file, now I get it in the service as a parameter

Hi @Egor.Litvinov 

Any XML->JSON conversion and reverse is the user's responsability. We don't have any snippets that perform such conversion automatically, but we do provide the required frameworks (JSON and E4X) to work with such content easily.

 

You can easily access the XML content by using the built-in E4X framework. It's extremely useful (and simple to use once you've invested <10 hours in it)

 

The following snippet gets you the DeliveryMaterialNumber (where x is the XML document you shared)

result = x.*::ContractProductions.*::ContractProduction[0].*::DeliveryMaterialNumber;

 

An e4x tutorial is available here: https://svn.wso2.org/repos/wso2/tags/carbon/0.1alpha/mashup/java/xdocs/e4xquickstart.html

The following link also shows some nice code snippets you can use https://community.ptc.com/t5/IoT-Tips/Parsing-XML-Data-especially-if-it-s-SOAP/ta-p/818774

I followed the example and wrote the following:

let myLogger = logger.getLoggerContext().getLogger(logger.getName() + ".com.ptc.sca.sco.SAPEndpoint");

// CreateInfoTableFromDataShape(infoTableName:STRING("InfoTable"), dataShapeName:STRING):INFOTABLE(Valenta.ProductionPlan)
let infoTable = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape({
	infoTableName: "InfoTable",
	dataShapeName: "Valenta.ProductionPlan"
});

//let changeXML = inputData.toString().split("n0:").join("");
let contractProductions = inputData.*::ContractProductions.*;
let stringXML = String(contractProductions)
logger.warn("stringXML: " + stringXML)

for each(let row in stringXML) {
	let newRow = Object();
	newRow.DeliveryNumber = row.*::DeliveryNumber;
	newRow.DeliveryItemNumber = row.*::DeliveryItemNumber;
	newRow.DeliveryMaterialNumber = row.*::DeliveryMaterialNumber;
	newRow.DeliveryMaterialShortName = row.*::DeliveryMaterialShortName;
	newRow.DeliveryUnits = row.*::DeliveryUnits;
	newRow.InboundDeliveryDocumentNumber = row.*::InboundDeliveryDocumentNumber;
	newRow.InboundDeliveryItemNumber = row.*::InboundDeliveryItemNumber;
	newRow.SupplierBatchCode = row.*::SupplierBatchCode;
	newRow.DeliveryPlanDate = row.*::DeliveryPlanDate;
	newRow.DeliveryPlanAmount = row.*::DeliveryPlanAmount;
	newRow.MaterialDocumentNumber = row.*::MaterialDocumentNumber;
	newRow.AccountingEntryDate = row.*::AccountingEntryDate;
	newRow.MaterialDocumentNumber = row.*::MaterialDocumentNumber;
	newRow.StockAmountReceived = row.*::StockAmountReceived;
	newRow.TargetAccountingChangeDate = row.*::TargetAccountingChangeDate;
	infoTable.AddRow(newRow);
}

// return info table
var result = infoTable

 But for some reason, my table is not filled with data. Where could I have gone wrong?

Specifically:

1. you are executing for each for lines in a String, then you use the XML accessors inside. You need to use the for each for nodes in the XML object, meaning there is no reason to cast to string (besides the logger statement)

2. You must specify in the the contractProductions XML object accessor that you want specifically all nodes of type ContractProduction. Otherwise the accessor as you wrote it it returns also other internal nodes. The toString output is identical, but the object is not.

result = x.*::ContractProductions.*::ContractProduction[0].*::DeliveryMaterialNumber;

//let myLogger = logger.getLoggerContext().getLogger(logger.getName() + ".com.ptc.sca.sco.SAPEndpoint");

// CreateInfoTableFromDataShape(infoTableName:STRING("InfoTable"), dataShapeName:STRING):INFOTABLE(Valenta.ProductionPlan)
let object = new Array();


//let changeXML = inputData.toString().split("n0:").join("");
contractProductions = x.*::ContractProductions.*::ContractProduction;
//let stringXML = String(contractProductions)
//logger.warn("stringXML: " + stringXML)

for each(let row in contractProductions) {
	let newRow = Object();
	newRow.DeliveryNumber = row.*::DeliveryNumber;
	newRow.DeliveryItemNumber = row.*::DeliveryItemNumber;
	newRow.DeliveryMaterialNumber = row.*::DeliveryMaterialNumber;
	newRow.DeliveryMaterialShortName = row.*::DeliveryMaterialShortName;
	newRow.DeliveryUnits = row.*::DeliveryUnits;
	newRow.InboundDeliveryDocumentNumber = row.*::InboundDeliveryDocumentNumber;
	newRow.InboundDeliveryItemNumber = row.*::InboundDeliveryItemNumber;
	newRow.SupplierBatchCode = row.*::SupplierBatchCode;
	newRow.DeliveryPlanDate = row.*::DeliveryPlanDate;
	newRow.DeliveryPlanAmount = row.*::DeliveryPlanAmount;
	newRow.MaterialDocumentNumber = row.*::MaterialDocumentNumber;
	newRow.AccountingEntryDate = row.*::AccountingEntryDate;
	newRow.MaterialDocumentNumber = row.*::MaterialDocumentNumber;
	newRow.StockAmountReceived = row.*::StockAmountReceived;
	newRow.TargetAccountingChangeDate = row.*::TargetAccountingChangeDate;
	object.push(newRow);
}

result = object

So I get two arrays of objects? Should I continue to work with them as with JSON or how?

Use this? Article - CS179012 - How to convert JSON to an InfoTable in ThingWorx (ptc.com)

Hi @Egor.Litvinov 

Because you did not supply the associated "Valenta.ProductionPlan" DataShape and I did not have time to generate a Datashape with the fields I see in code, I modified your code to add the information in an Array of JSON objects. I did not mention this modification - sorry.

You should only take a look at the specific points I mentioned above.

.For point 1:

for each(let row in contractProductions) {

 and for point 2

contractProductions = x.*::ContractProductions.*::ContractProduction;

I finally managed to find a solution. On the forum, I found a service for converting XML to JSON, and then I folded the JSON object into an infotable. Thanks for the help @VladimirRosu 

 

// result: JSON
let getJSON = me.ConvertXmlToJSON({
	xml: inputData /* XML */
});

// CreateInfoTableFromDataShape(infoTableName:STRING("InfoTable"), dataShapeName:STRING):INFOTABLE(Valenta.ProductionPlan)
let infoTable = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape({
	infoTableName: "InfoTable",
	dataShapeName: "Valenta.ProductionPlan"
});

for (let i = 0; i < getJSON.ContractProductions.ContractProduction.length; i++) {
	infoTable.AddRow({
		DeliveryNumber: getJSON.ContractProductions.ContractProduction[i].DeliveryNumber,
		DeliveryItemNumber: getJSON.ContractProductions.ContractProduction[i].DeliveryItemNumber,
		DeliveryMaterialNumber: getJSON.ContractProductions.ContractProduction[i].DeliveryMaterialNumber,
		DeliveryMaterialShortName: getJSON.ContractProductions.ContractProduction[i].DeliveryMaterialShortName,
		DeliveryUnits: getJSON.ContractProductions.ContractProduction[i].DeliveryUnits,
		InboundDeliveryDocumentNumber: getJSON.ContractProductions.ContractProduction[i].InboundDeliveryDocumentNumber,
		InboundDeliveryItemNumber: getJSON.ContractProductions.ContractProduction[i].InboundDeliveryItemNumber,
		SupplierBatchCode: getJSON.ContractProductions.ContractProduction[i].SupplierBatchCode,
		DeliveryPlanDate: getJSON.ContractProductions.ContractProduction[i].DeliveryPlanDate,
		DeliveryPlanAmount: getJSON.ContractProductions.ContractProduction[i].DeliveryPlanAmount,
		MaterialDocumentNumber: getJSON.ContractProductions.ContractProduction[i].MaterialDocumentNumber,
		AccountingEntryDate: getJSON.ContractProductions.ContractProduction[i].AccountingEntryDate,
		StockAmountReceived: getJSON.ContractProductions.ContractProduction[i].StockAmountReceived,
		TargetAccountingChangeDate: getJSON.ContractProductions.ContractProduction[i].TargetAccountingChangeDate
	});
}

let result = infoTable;

 

 

Announcements


Top Tags