Community Tip - Want the oppurtunity to discuss enhancements to PTC products? Join a working group! X
Эй! На данный момент я помещаю 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 и помещать значения в таблицу. Все, что я нашел на форумах, не помогло. Может быть, вы можете мне помочь?
Solved! Go to Solution.
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;
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.
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
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)
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;