Javascript 在服务器端NetSuite中从自动任务导航XML
我正在研究某人的NetSuite帐户和他们的自动任务帐户之间的集成。它从自动任务接收数据,在NetSuite中创建记录,然后将部分数据传递回自动任务。自动任务的工作方式似乎是,我必须删除接收到的XML的一个块,对其进行更改,然后将更新后的块直接发布回系统,否则它会删除未包含的任何内容。因此,在将XML作为文本接收后,我使用函数nlapiStringToXML()将其转换为XML对象:Javascript 在服务器端NetSuite中从自动任务导航XML,javascript,xml,netsuite,Javascript,Xml,Netsuite,我正在研究某人的NetSuite帐户和他们的自动任务帐户之间的集成。它从自动任务接收数据,在NetSuite中创建记录,然后将部分数据传递回自动任务。自动任务的工作方式似乎是,我必须删除接收到的XML的一个块,对其进行更改,然后将更新后的块直接发布回系统,否则它会删除未包含的任何内容。因此,在将XML作为文本接收后,我使用函数nlapiStringToXML()将其转换为XML对象: var xmlObj = nlapiStringToXML(xmlString); eObj ==> {
var xmlObj = nlapiStringToXML(xmlString);
eObj ==> {string} org.apache.xerces.dom.DeepNodeListImpl@239776f9
我对数据进行了一些测试,以获得所需的数据。以下是接收到的XML示例:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<queryResponse xmlns="http://autotask.net/ATWS/v1_5/">
<queryResult>
<ReturnCode>1</ReturnCode>
<EntityResults>
<Entity xsi:type="Ticket">
<id>54606</id>
<UserDefinedFields>
<UserDefinedField>
<Name>3rd Party Case Number</Name>
</UserDefinedField>
<UserDefinedField>
<Name>Check in Text Single Line</Name>
</UserDefinedField>
<UserDefinedField>
<Name>Escalation Case Number</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Additional Max Hours</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Additional Pay Rate</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Check In</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Check In MultiLine</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Check in Numeric</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Check Out</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Closing Notes</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN HD Name You Closed With</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Manager On Duty</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Max Hours/Devices</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Pay Mode</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Pay Rate</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Provider Cell Number</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Provider Name</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Return Tracking #</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Scheduled Date and Time</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Status</Name>
</UserDefinedField><UserDefinedField>
<Name>FN Total Amount</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FN Work Order ID</Name>
</UserDefinedField>
<UserDefinedField>
<Name>FOLLOW-UP NEEDED</Name>
</UserDefinedField>
<UserDefinedField>
<Name>Kaseya Alert ID</Name>
</UserDefinedField>
<UserDefinedField>
<Name>Kaseya Ticket ID</Name>
</UserDefinedField>
<UserDefinedField>
<Name>Netsuite Case Internal Id</Name>
<Value>-2</Value>
</UserDefinedField>
<UserDefinedField>
<Name>Netsuite Case Number</Name>
</UserDefinedField>
<UserDefinedField>
<Name>New HW SN Number</Name>
</UserDefinedField>
<UserDefinedField>
<Name>Old HW SN Number</Name>
</UserDefinedField>
<UserDefinedField>
<Name>RMA</Name>
</UserDefinedField>
<UserDefinedField>
<Name>Sales Order</Name>
</UserDefinedField>
<UserDefinedField>
<Name>SB OLO?</Name>
</UserDefinedField>
</UserDefinedFields>
<AccountID xsi:type="xsd:int">000</AccountID>
<AllocationCodeID xsi:type="xsd:int">00000000</AllocationCodeID>
<CreateDate xsi:type="xsd:dateTime">2018-04-12T08:49:54.323</CreateDate>
<CreatorResourceID xsi:type="xsd:int">29682898</CreatorResourceID>
<Description xsi:type="xsd:string">Integration Testing</Description>
<DueDateTime xsi:type="xsd:dateTime">2018-04-13T08:47:00</DueDateTime>
<IssueType xsi:type="xsd:int">17</IssueType>
<LastActivityDate xsi:type="xsd:dateTime">2018-04-12T08:50:11.1</LastActivityDate>
<Priority xsi:type="xsd:int">1</Priority>
<AssignedResourceID xsi:type="xsd:int">00000000</AssignedResourceID>
<AssignedResourceRoleID xsi:type="xsd:int">00000000</AssignedResourceRoleID>
<Source xsi:type="xsd:int">8</Source>
<Status xsi:type="xsd:int">1</Status>
<SubIssueType xsi:type="xsd:int">282</SubIssueType>
<TicketNumber xsi:type="xsd:string">T00000000.0000</TicketNumber>
<Title xsi:type="xsd:string">Integration Testing</Title>
<FirstResponseDueDateTime xsi:type="xsd:dateTime">2018-04-12T12:49:54.323</FirstResponseDueDateTime>
<ResolvedDueDateTime xsi:type="xsd:dateTime">2018-04-13T08:49:54.323</ResolvedDueDateTime>
<ServiceLevelAgreementID xsi:type="xsd:int">1</ServiceLevelAgreementID>
<Resolution xsi:type="xsd:string"/><PurchaseOrderNumber xsi:type="xsd:string"/>
<TicketType xsi:type="xsd:int">2</TicketType>
<ChangeInfoField1 xsi:type="xsd:string"/>
<ChangeInfoField2 xsi:type="xsd:string"/>
<ChangeInfoField3 xsi:type="xsd:string"/>
<ChangeInfoField4 xsi:type="xsd:string"/>
<ChangeInfoField5 xsi:type="xsd:string"/>
<TicketCategory xsi:type="xsd:int">3</TicketCategory>
<ExternalID xsi:type="xsd:string"/>
</Entity>
</EntityResults>
<EntityResultType>ticket</EntityResultType>
<Errors/>
<EntityReturnInfoResults>
<EntityReturnInfo>
<EntityId>54606</EntityId>
<DatabaseAction>None</DatabaseAction>
<DuplicateStatus>
<Found>false</Found>
<MatchInfo/>
<Ignored>false</Ignored>
</DuplicateStatus>
<Message/>
</EntityReturnInfo>
</EntityReturnInfoResults>
</queryResult>
</queryResponse>
</soap:Body>
</soap:Envelope>
但是,在服务器端执行时,会导致以下错误:
Java class "org.apache.xerces.dom.DeepNodeListImpl" has no public instance field or method named "0"
使用NetSuite的调试器来检查并解决这个问题,看起来我得到的是一个测试字符串而不是XML对象:
var xmlObj = nlapiStringToXML(xmlString);
eObj ==> {string} org.apache.xerces.dom.DeepNodeListImpl@239776f9
我必须通过以下途径获得所需的块:
var eObj = xmlObj.childNodes.firstChild.childNodes.firstChild.childNodes.firstChild.childNodes.firstChild.childNodes.firstChild.getNextSibling().firstChild;
我知道NetSuite有XML导航方法,但我发现它们不可靠。上面的方法假设所有内容都将始终处于相同的精确位置,我不喜欢这样,因为如果返回的值使用新的或删除的值进行更改,则这将中断。特别是考虑到我需要调出UserDefinedFields元素并遍历子元素并更新其中的一小部分。我打算运行,检查“Name”是否与某些值匹配,然后向“UserDefinedField”元素添加一个“Value”标记以进行匹配。但是,考虑到我正在使用的这种结构(这与调试器中显示的对象结构不同),我对如何迭代这些子元素、找到需要更新的内容并完成任务感到困惑。这是我计划使用的,它似乎在浏览器控制台中工作:
for (var i = 0; i < eObj.getElementsByTagName("UserDefinedField").length; i++) {
if (eObj.getElementsByTagName("UserDefinedField")[i].getElementsByTagName("Name")[0].innerHTML == "FIELD_NAME") {
var vObjArr = eObj.getElementsByTagName("UserDefinedField")[i].getElementsByTagName("Value");
if (_tools.isEmpty(vObjArr) || vObjArr.length == 0) {
var vObjA = xmlObj.createElement("Value");
var vObjB = xmlObj.createTextNode("VALUE");
vObjA.appendChild(vObjB);
eObj.getElementsByTagName("UserDefinedField")[i].appendChild(vObjA);
} else {
eObj.getElementsByTagName("UserDefinedField")[i].getElementsByTagName("Value")[0].innerHTML = "VALUE";
}
}
if (/* additional values checks here*/) {
// do stuff
}
}
for(var i=0;i
面对呈现给我的新现实,我对如何改变这一点一无所知。而不是:
var eObj = xmlObj.getElementsByTagName("Entity")[0];
使用以下命令:
var eObj = xmlObj.getElementsByTagName("Entity").item(0)
因为返回对象是一个DeepNodeListImpl,并且类实现了一个methode项(int index),它返回指定索引处的节点。它还有一个getLength(),返回节点列表的长度。。有关更多说明,请参阅
希望它能有所帮助。这个效果非常好。但我必须走一条完全不同的道路,使用正则表达式提取xml文本。我需要将提取的xml块转换回字符串,以转换为响应xml,但方法nlapiXMLToString()忽略该块,因为它显然是一个“元素”而不是“文档”。但还是非常感谢你,因为我知道我会再次需要这个。我很高兴它能帮助你。我没有真正测试所有的东西,我没有环境,这就是为什么我不能更具体,那么我仍然为此感到抱歉。