日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Transformation available that removes all elements from form message type

發布時間:2023/12/19 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Transformation available that removes all elements from form message type 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

The elements which are used in the form message type for a specific form can be classfied as four types:

  • direct binding.
  • Example: in direct binding, the element path is just specified in the attribute “field.bind.ref”, as shown below.

    <field access="readOnly" minH="6.2mm" name="txtCustomerID" w="85mm"> <font typeface="Arial"/> <margin bottomInset="1.2mm" leftInset="0mm" rightInset="0mm" topInset="0mm"/> <caption reserve="39mm"> <font typeface="Arial" weight="bold"/> <value> <text>Customer ID:</text> </value> </caption> <bind match="dataRef" ref="$record.DeliveryNote.ProductRecipientParty.InternalID"/> <sapa1s xmlns="http://www.sap.com/a1s/cd/om/forms/config"><InfoBlockItem configurable="false" copyForCustomFields="false"><Description lang="en">Customer ID</Description></InfoBlockItem></sapa1s> </field>
  • relative binding.
    Example: form template field form message type instance
    A ( parent ) $record.DeliveryNote.Material
    a ( child ) $.ID
    b ( child ) $.ItemID
    c ( child ) $.Name
    If some node in the same hierarchy are bound to the same parent node in the form message type, for this example “a” is bound to $record.DeliveryNote.Material.ID and “b” is bound to $record.DeliveryNote.Material.ItemID and “c” is bound to $record.DeliveryNote.Material.Name. To enhance performance, we use relative binding. The parent of a,b, and c is bound to $record.DeliveryNote.Material and “a” now is bound to $.ID and “b” $.ItemID and “c” $.Name.
  • <field access="readOnly" minH="2mm" name="colIndex" w="30mm" x="0mm" y="0mm"> <font size="9pt" typeface="Arial"/> <margin bottomInset="1mm" leftInset="1mm" rightInset="1mm" topInset="1mm"/> <bind match="dataRef" ref="$.ItemID"/> <assist> <speak disable="1"/> </assist> </field>
  • direct scripting.
    As mentioned by Patrick, it is impossible to fulfill some special requirement sometimes so java script is used to handle with some form message type elements.
  • All the script texts for a field is located in the field.event.script node in the xml source.
    We call some type as “direct scripting” because the specified form message type elements can still be found in the script text, as example below:

    $DeliveryNote.LogisticPackage.Material.PurchaseOrderItemReference.ID ( just concatenate the path after “resolveNode” function ).

  • relative scripting.
    We call “relative scripting” because the path of the form message type elements used is more implicit to be detected compared with direct scripting. Relative scripting is mainly used to benefit from making table accessible and EFE compatible.
  • Example: var d = this.dataNode.parent.parent.

    We cannot get anything from the script above until going up in the form message type instance hierarchy. Field “txtLUID” is relatively bound to “TargetLogisticsAreaDescription”.
    So we can know that in this script, the element LogisticPackage.LogisticUnitID and LogisticPackage.PlannedLogisticUnitQuantity is used.
    To achieve this:

    step1: load the xml source of a template into memory. You can find that I just ignore the xml source " content balalala" because those source are irrrelevant for field binding path and the more important thing is , I find the Java DOM can not handle with some special locale characters, for example ,the locale characters in Chinese, so I just ignore them.

    if( CheckifXDPFile(inputXDPFile) == false ) return null; String XMLOutput = getFileNameExcludingExt(inputXDPFile); XMLOutput += ".xml"; br = new BufferedReader(new FileReader(inputXDPFile)); bw = new BufferedWriter(new FileWriter(XMLOutput)); System.out.println("Begin to Copy File"); File XML = new File(inputXDPFile); int length = (int)XML.length(); char[] inputdata = new char [length]; br.read(inputdata,0,length); String input = new String(inputdata); int indexlocale = input.indexOf("<localeSet"); if( indexlocale == -1) { // the template has no localeSet node! bw.write(inputdata); br.close(); bw.close(); return XMLOutput; } String before = input.substring(0,indexlocale); int postindex = input.indexOf("</localeSet>"); String locale = "</localeSet>"; String post = input.substring(postindex + locale.length()); String finalString = before.concat(post); bw.write(finalString); br.close(); bw.close(); return XMLOutput;

    step2: build the xml source got from step1 into DOM tree.

    import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException;private DocumentBuilderFactory domfac; private DocumentBuilder dombuilder; private Document doc;InputStream inputXML = new FileInputStream(OutputXMLFile); doc = dombuilder.parse(inputXML); Element root = doc.getDocumentElement(); Node template = Tool.getNodebyRoot("template",root); if( template == null) return null;

    An example of DOM tree looks like below. Here what you have to do is just to go through the node for master page and the one for body page recursively and get all the subnode filtered by node name “field”.
    This is because only element “field” and “subform” can have binding path from technical side, if you need also to extract binding path of subform, you must also handle with the node whose name is “subform”.

    step3: suppose you have already get a node for “field”, you can find from the xml source for this field below and know that the binding path is located in the subnode named “bind”, attribute “ref”.

    <field access="readOnly" minH="6.2mm" name="txtLogLocation1" w="85mm"> <ui> <textEdit multiLine="1"> </textEdit> </ui> <font baselineShift="0pt" typeface="Arial"/> <margin bottomInset="0mm" leftInset="0mm" rightInset="0mm" topInset="0mm"/> <caption reserve="40mm"> <font baselineShift="0pt" typeface="Arial" weight="bold"/> <value> <text> </text> </value> </caption> <bind match="dataRef" ref="$record.SiteLogisticsTask.LogisticsLocationDescription"/> <assist> <speak priority="caption"/> </assist>

    you can get its binding path such as below:

    private void getFieldBindingInfo(Node node) { Node BindNode = Tool.getNodebyRoot("bind",node); if( BindNode == null) { // this node has none binding path at all !! return; } else { if( BindNode.getAttributes().getNamedItem("ref") == null) // none binding { return; } else { bindingPath = BindNode.getAttributes().getNamedItem("ref").getNodeValue(); // bind path is stored in bindingPath! } }

    whole source code

    package formAutoBinding;import utilities.*; import excelFormat.internalStructure.*; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Vector; import javax.swing.DefaultListModel; import javax.swing.JList; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException;public class TemplateBindingProcessor { private DocumentBuilderFactory domfac;private DocumentBuilder dombuilder;private FileCopyFactory filecopy;private Document doc;private Element root;private String tablePath = null;private HashMap<String,internalPathObject> bindingpathCollection = null;private Vector<String> TableCellNameVec = null;private Vector<String> NormalBindingVec = null;private Vector<String> NoneBindingVec = null;private JList jListforBindingInfo = null;private DefaultListModel listModeforBindingInfo = null;private int nBoundFieldNumber = 0;private int nUnBoundFieldNumber = 0; public TemplateBindingProcessor(HashMap<String,internalPathObject> collection) { bindingpathCollection = collection; domfac = DocumentBuilderFactory.newInstance(); NormalBindingVec = new Vector<String>(); NoneBindingVec = new Vector<String>(); try { dombuilder = domfac.newDocumentBuilder(); } catch (ParserConfigurationException e) {e.printStackTrace(); } }public Element getRoot() { return root; }private String comparePrefix(String pre1,String pre2) { System.out.println("Compare pre1: " + pre1 + " pre2: " + pre2); if(( pre1 == null) || ( pre2 == null)) return null; return pre1.length() > pre2.length()? pre2:pre1;} private String getMaxPrefix(Vector<String> c) { int size = c.size(); if( size <= 1) { System.out.println("Only : " + size + " elements in the table!"); return null; } String s1 = c.elementAt(0); String s2 = c.elementAt(1); String finalprefix = null; String tempprefix = getMaxPrefixwithTwoString(s1,s2); for( int i = 2 ; i < size; i++ ) { s1 = tempprefix; s2 = c.elementAt(i); finalprefix = getMaxPrefixwithTwoString(s1,s2); finalprefix = comparePrefix(tempprefix,finalprefix); } if( finalprefix == null) System.out.println("Error: Can not find Table Row Binding Path"); else System.out.println("Table Path: " + finalprefix); return finalprefix; } private String getMaxPrefixwithTwoString(String n1,String n2) { int length1 = n1.length(); int length2 = n2.length(); int i = 0; while(i < length1 && i < length2) { if( n1.charAt(i) != n2.charAt(i)) break; i++; } if( i == 0 ) return null; String temp = n1.substring(0,i); System.out.println("String1: " + n1 + " String2: " + n2 + " prefix->" + temp); return temp; }public void PrintBindingStatistics(JList jlist,DefaultListModel mode) { jListforBindingInfo = jlist; listModeforBindingInfo = mode; listModeforBindingInfo.clear(); jListforBindingInfo.setModel(listModeforBindingInfo); Node templateNode = Tool.getNodebyRoot("template",root); if( templateNode == null ) return; traverse(templateNode); String item = "Total Bound Field Number: " + nBoundFieldNumber; listModeforBindingInfo.addElement(item); item = "Total Unbound Field Number: " + nUnBoundFieldNumber; listModeforBindingInfo.addElement(item); listModeforBindingInfo.addElement("\n"); int normalBindingNumber = NormalBindingVec.size(); for( int i = 0 ; i < normalBindingNumber; i++) { item = "Field: " + NormalBindingVec.elementAt(i) + " has normal binding!"; listModeforBindingInfo.addElement(item); listModeforBindingInfo.addElement("\n"); } int noneBindingNumber = NoneBindingVec.size(); for( int j = 0 ; j < noneBindingNumber; j++) { item = "Field: " + NoneBindingVec.elementAt(j) + " binding set to NONE!"; listModeforBindingInfo.addElement(item); listModeforBindingInfo.addElement("\n"); } } // save all the information in the listmode into a file public String SaveLogFile(String path) { int index = path.lastIndexOf('.'); if ( index == -1) path += ".html"; try { FileLogFactory log = new FileLogFactory(path); int lognumber = listModeforBindingInfo.size(); for( int i = 0 ; i < lognumber; i++) { log.WriteToLogFile(listModeforBindingInfo.elementAt(i).toString()); } log.CloseFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return path;} private void traverse(Node node) { NodeList child = node.getChildNodes(); int childNumber = child.getLength(); Node item = null; for( int i = 0 ;i < childNumber; i++) { item = child.item(i); if( item.getNodeName().equals("subform") || item.getNodeName().equals("subformSet")) traverse(item); else if ( item.getNodeName().equals("field")) getFieldBindingInfo(item); else if ( item.getNodeName().equals("pageSet")) getMasterPageBindingInfo(item); } }private void getFieldBindingInfo(Node node) { String fieldName = null; String bindingPath = null; if( node.getAttributes().getNamedItem("name") == null ) fieldName = "DefaultField"; else fieldName = node.getAttributes().getNamedItem("name").getNodeValue(); Node BindNode = Tool.getNodebyRoot("bind",node); if( BindNode == null) { nUnBoundFieldNumber++; NormalBindingVec.add(fieldName); } else { if( BindNode.getAttributes().getNamedItem("ref") == null) // none binding { nUnBoundFieldNumber++; NoneBindingVec.add(fieldName); } else { bindingPath = BindNode.getAttributes().getNamedItem("ref").getNodeValue(); nBoundFieldNumber++; String item = "Field: " + fieldName; listModeforBindingInfo.addElement(item); item = "Bound to path: " + bindingPath + " Successfully!"; listModeforBindingInfo.addElement(item); listModeforBindingInfo.addElement("\n"); } }} private void getMasterPageBindingInfo(Node item) { NodeList masterChild = item.getChildNodes(); Node masterPageitem = null; int masterChildLength = masterChild.getLength(); for (int j = 0; j < masterChildLength; j++) { masterPageitem = masterChild.item(j); if (masterPageitem.getNodeName().equals("pageArea")) { traverse(masterPageitem); } } }private boolean isNodeTableRow(Node node) { if( Tool.isFieldHidden(node)) return false; if( node.getNodeName().equals("subformSet")) return false; if( node.getAttributes().getNamedItem("layout") == null ) return false; String layoutStyle = node.getAttributes().getNamedItem("layout").getNodeValue(); if( !layoutStyle.equals("row")) return false; // should filter out the header row: for header row need not bind at all int fieldNumber = 0; NodeList child = node.getChildNodes(); int childnumber = child.getLength(); for( int i = 0 ; i < childnumber; i++) { if( child.item(i).getNodeName().equals("field")) fieldNumber++; } if( fieldNumber == 0 ) { System.out.println("This node need not bind!"); return false; } return true; }private void BindTableRow(Node node) { NodeList child = node.getChildNodes(); int childnumber = child.getLength(); Node item = null; String fieldName = null; internalPathObject pathObj = null; TableCellNameVec = new Vector<String>(); for( int i = 0 ; i < childnumber;i++) { item = child.item(i); if( item.getNodeName().equals("field")) { fieldName = FetchFieldDefaultValue(item); // get path pathObj = bindingpathCollection.get(fieldName); /* this situation means some fields are not bound directly but * its value is assigned through some else fields within hidden field */ if( pathObj == null) continue; System.out.println("Adding Table Cell Path:" + pathObj.getPath()); TableCellNameVec.add(pathObj.getPath()); } // also search the field path within the hidden subform else if (( item.getNodeName().equals("subform")) && ( Tool.isFieldHidden(item))) { // get all the fields within hidden subform RecursiveFillFieldName(item); } } tablePath = getMaxPrefix(TableCellNameVec); TableCellNameVec.clear(); TableCellNameVec = null; System.out.println("Table Path: " + tablePath); tablePath = tablePath.substring(0,tablePath.length()-1); System.out.println("Table Path: " + tablePath); // append bind node to table node AppendTableBindNode(node);}private void RecursiveFillFieldName(Node node) { NodeList child = node.getChildNodes(); int number = child.getLength(); Node item = null; String fieldName = null; internalPathObject pathObj = null; for( int i = 0 ; i < number; i++) { item = child.item(i); if( item.getNodeName().equals("field")) { fieldName = FetchFieldDefaultValue(item); System.out.println("FiledName**********: " + fieldName); // get path pathObj = bindingpathCollection.get(fieldName); /* this situation means some fields are not bound directly but * its value is assigned through some else fields within hidden field */ if( pathObj == null) continue; System.out.println("Adding........Table Cell: " + pathObj.getPath()); TableCellNameVec.add(pathObj.getPath()); } else if ( item.getNodeName().equals("subform")) RecursiveFillFieldName(item); } } private void AppendTableBindNode(Node item) { Node BindNode = Tool.getNodebyRoot("bind",item); if( BindNode == null) // normal binding AppendMatchNodeandDoBinding(item,null); else if( BindNode.getAttributes().getNamedItem("match").getNodeValue().equals("none")) // none binding ModifyMatchValueandDoBinding(item,BindNode,null); else // overwrite the previous binding path OverWritePreviousPath(item,BindNode,null); } public void StartTemplateBinding(String path) { LoadTemplateFile(path); System.out.println("Load Template Successfully!"); root = doc.getDocumentElement(); Node templateNode = Tool.getNodebyRoot("template",root); if( templateNode == null ) return; System.out.println("Start auto binding!"); AutoBindTemplate(templateNode); }private void AutoBindTemplate(Node parent) { NodeList child = parent.getChildNodes(); Node item = null; int childLength = child.getLength(); for (int i = 0; i < childLength; i++) { item = child.item(i); // Should take subform set into consideration if ((item.getNodeName().equals("subform")) || (item.getNodeName().equals("subformSet"))) { // should dynamically find the max prefix, that is the binding path // of the table row ! if( isNodeTableRow( item )) BindTableRow( item ); AutoBindTemplate(item); } else if (item.getNodeName().equals("pageSet")) { NodeList masterChild = item.getChildNodes(); Node masterPageitem = null; int masterChildLength = masterChild.getLength(); for (int j = 0; j < masterChildLength; j++) { masterPageitem = masterChild.item(j); if (masterPageitem.getNodeName().equals("pageArea")) { HandlePageArea(masterPageitem); } } } // field not in the table else if (item.getNodeName().equals("field")) { // start real auto binding process here System.out.println("Detect a field"); AutoBindField(item); } } } private void HandlePageArea(Node PageArea) { NodeList child = PageArea.getChildNodes(); Node item = null; int childLength = child.getLength(); for (int i = 0; i < childLength; i++) { item = child.item(i); // Should take subform set into consideration if ((item.getNodeName().equals("subform")) || (item.getNodeName().equals("subformSet"))) { AutoBindTemplate(item); } else if (item.getNodeName().equals("field")) { //start real auto binding process here AutoBindField(item); } }} private String GetDecimalDefaultValue(Node ValueNode) { Node decimalNode = Tool.getNodebyRoot("decimal",ValueNode); if( decimalNode == null) return null; return decimalNode.getTextContent(); } private String FetchFieldDefaultValue(Node node) { Node valueNode = Tool.getNodebyRoot("value",node); if( valueNode == null) { System.out.println("Cannot find value node within the field node"); return null; } Node textNode = Tool.getNodebyRoot("text",valueNode); if( textNode == null) { System.out.println("Cannot find text node within the value node"); // one more check: if it is a decimal field ? return GetDecimalDefaultValue(valueNode); } System.out.println("Default Value: " + textNode.getTextContent()); return textNode.getTextContent(); } // Caption Name is a generic definition which means the identificator // of a field in the template private void AutoBindField(Node item) { String CaptionName = FetchFieldCaption(item); if( CaptionName == null) { CaptionName = FetchFieldDefaultValue(item); if( CaptionName == null ) return; } System.out.println("Field to be auto bound:->" + CaptionName); internalPathObject obj = bindingpathCollection.get(CaptionName); if( obj == null ) { System.out.println("Try to bind field: " + CaptionName + " but fail to find path in PathCollection"); return; } Node BindNode = Tool.getNodebyRoot("bind",item); System.out.println("Field: " + CaptionName + " Path: " + obj.getPath() + " Can be bound now!"); if( BindNode == null) // normal binding AppendMatchNodeandDoBinding(item,obj); else if( BindNode.getAttributes().getNamedItem("match").getNodeValue().equals("none")) // none binding ModifyMatchValueandDoBinding(item,BindNode,obj); else // overwrite the previous binding path OverWritePreviousPath(item,BindNode,obj); }private void OverWritePreviousPath(Node parentNode,Node OldBindNode,internalPathObject obj) { // the same logic as the none-binding ModifyMatchValueandDoBinding(parentNode,OldBindNode,obj); } /* take delivery Note for example, should check if a field is in a table row. * only in the table row can use relative binding currently. up to 3 * level may be enough. */ private boolean checkIfinTableRow(Node node) { System.out.println("in CheckIfinTableRow()"); String layoutAttr = null; Node parent = node.getParentNode(); for( int i = 0 ; i < 3; i++ ) { if( parent == null ) return false; if( parent.getAttributes().getNamedItem("layout") == null ) { parent = parent.getParentNode(); continue; } else { layoutAttr = parent.getAttributes().getNamedItem("layout").getNodeValue(); if( layoutAttr.equals("row")) { System.out.println("Found a table Row: " + parent.getAttributes().getNamedItem("name").getNodeValue()); return true; } } parent = parent.getParentNode(); } return false; } private void ModifyMatchValueandDoBinding(Node parentNode,Node OldBindNode,internalPathObject obj) { Document CellDocument = parentNode.getOwnerDocument(); Element NewbindNode = CellDocument.createElement("bind"); Attr matchFlag = CellDocument.createAttribute("match"); matchFlag.setNodeValue("dataRef"); NewbindNode.setAttributeNode(matchFlag); String realBindPath = null; if( obj == null) { // means it is a table row realBindPath = tablePath + "[*]"; } else if( obj.isInTable() ) {// should use relative path instead System.out.println("Field: " + obj.getRelativePath() + " is in table"); if( checkIfinTableRow(parentNode)) realBindPath = getRelativePath(obj); else { realBindPath = obj.getPath(); }} else realBindPath = obj.getPath(); Attr Boundpath = CellDocument.createAttribute("ref"); Boundpath.setNodeValue(realBindPath); NewbindNode.setAttributeNode(Boundpath); parentNode.replaceChild(NewbindNode, OldBindNode); System.out.println("Add a New Bind Node");} private String getRelativePath(internalPathObject obj) { String completePath = obj.getPath(); String relativePath = completePath.substring(tablePath.length(),completePath.length()); System.out.println("Relative Path: " + relativePath); relativePath = "$" + relativePath; return relativePath; } private void AppendMatchNodeandDoBinding(Node node,internalPathObject obj) {Document CellDocument = node.getOwnerDocument(); Element bindNode = CellDocument.createElement("bind"); Attr matchFlag = CellDocument.createAttribute("match"); matchFlag.setNodeValue("dataRef"); bindNode.setAttributeNode(matchFlag);Attr Boundpath = CellDocument.createAttribute("ref"); String realBindPath = null; if( obj == null) { // means it is a table row realBindPath = tablePath + "[*]"; } else if( obj.isInTable()) { System.out.println("Field: " + obj.getRelativePath() + " is in table"); if( checkIfinTableRow(node)) realBindPath = getRelativePath(obj); else { realBindPath = obj.getPath(); } } else realBindPath = obj.getPath(); System.out.println("Real Bound path: " + realBindPath); Boundpath.setNodeValue(realBindPath); bindNode.setAttributeNode(Boundpath);node.appendChild(bindNode); }private String FormatSavePath(String path) { int index = path.lastIndexOf('.'); if( index != -1) return path; String newPath = path + ".xdp"; return newPath; }public String SaveAs(String path) { String formattedPath = FormatSavePath(path); File newFile = new File(formattedPath); if( newFile.exists()) return null; try { TransformerFactory tff = TransformerFactory.newInstance(); Transformer tf = tff.newTransformer(); DOMSource source = new DOMSource(doc); File newXDPFile = new File(formattedPath); StreamResult rs = new StreamResult(newXDPFile); tf.transform(source,rs); tf.reset();} catch(Exception e1) { e1.printStackTrace(); } return path; }// currently can only match field by caption private String FetchFieldCaption(Node item) { Node captionNode = Tool.getNodebyRoot("caption",item); if( captionNode == null) { //System.out.println("Cannot find caption node within the field node"); return null; } Node valueNode = Tool.getNodebyRoot("value",captionNode); if( valueNode == null) { //System.out.println("Cannot find value node within the caption node"); return null; } Node textNode = Tool.getNodebyRoot("text",valueNode); if( textNode == null) { //System.out.println("Cannot find text node within the value node"); return null; } System.out.println("Caption Name: " + textNode.getTextContent()); return textNode.getTextContent();} public void LoadTemplateFile(String inputXDPName) { try { filecopy = new FileCopyFactory(); String OutputXMLFile = filecopy.copyFile(inputXDPName); if (OutputXMLFile == null) return; InputStream inputXML = new FileInputStream(OutputXMLFile); doc = dombuilder.parse(inputXML); root = doc.getDocumentElement(); // but only template DOM is our concern... filecopy.DeleteUnusedXML(OutputXMLFile); }catch (FileNotFoundException d) { d.printStackTrace(); } catch (SAXException d) { d.printStackTrace(); System.exit(0); } catch (IOException d) { d.printStackTrace(); }} }

    要獲取更多Jerry的原創文章,請關注公眾號"汪子熙":

    總結

    以上是生活随笔為你收集整理的Transformation available that removes all elements from form message type的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。