OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 | |
7 #include "xfa/fxfa/parser/xfa_document_serialize.h" | |
8 | |
9 #include "xfa/fde/xml/fde_xml_imp.h" | |
10 #include "xfa/fgas/crt/fgas_codepage.h" | |
11 #include "xfa/fxfa/parser/cxfa_document.h" | |
12 #include "xfa/fxfa/parser/cxfa_simple_parser.h" | |
13 #include "xfa/fxfa/parser/xfa_localemgr.h" | |
14 #include "xfa/fxfa/parser/xfa_object.h" | |
15 #include "xfa/fxfa/parser/xfa_utils.h" | |
16 | |
17 CXFA_DataImporter::CXFA_DataImporter(CXFA_Document* pDocument) | |
18 : m_pDocument(pDocument) { | |
19 ASSERT(m_pDocument); | |
20 } | |
21 FX_BOOL CXFA_DataImporter::ImportData(IFX_FileRead* pDataDocument) { | |
22 std::unique_ptr<CXFA_SimpleParser> pDataDocumentParser( | |
23 new CXFA_SimpleParser(m_pDocument, false)); | |
24 if (!pDataDocumentParser) | |
25 return FALSE; | |
26 | |
27 if (pDataDocumentParser->StartParse(pDataDocument, XFA_XDPPACKET_Datasets) != | |
28 XFA_PARSESTATUS_Ready) { | |
29 return FALSE; | |
30 } | |
31 if (pDataDocumentParser->DoParse(nullptr) < XFA_PARSESTATUS_Done) | |
32 return FALSE; | |
33 | |
34 CXFA_Node* pImportDataRoot = pDataDocumentParser->GetRootNode(); | |
35 if (!pImportDataRoot) | |
36 return FALSE; | |
37 | |
38 CXFA_Node* pDataModel = | |
39 ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Datasets)); | |
40 if (!pDataModel) | |
41 return FALSE; | |
42 | |
43 CXFA_Node* pDataNode = ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Data)); | |
44 if (pDataNode) | |
45 pDataModel->RemoveChild(pDataNode); | |
46 | |
47 if (pImportDataRoot->GetElementType() == XFA_Element::DataModel) { | |
48 while (CXFA_Node* pChildNode = | |
49 pImportDataRoot->GetNodeItem(XFA_NODEITEM_FirstChild)) { | |
50 pImportDataRoot->RemoveChild(pChildNode); | |
51 pDataModel->InsertChild(pChildNode); | |
52 } | |
53 } else { | |
54 CFDE_XMLNode* pXMLNode = pImportDataRoot->GetXMLMappingNode(); | |
55 CFDE_XMLNode* pParentXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::Parent); | |
56 if (pParentXMLNode) | |
57 pParentXMLNode->RemoveChildNode(pXMLNode); | |
58 pDataModel->InsertChild(pImportDataRoot); | |
59 } | |
60 m_pDocument->DoDataRemerge(FALSE); | |
61 return TRUE; | |
62 } | |
63 | |
64 CFX_WideString XFA_ExportEncodeAttribute(const CFX_WideString& str) { | |
65 CFX_WideTextBuf textBuf; | |
66 int32_t iLen = str.GetLength(); | |
67 for (int32_t i = 0; i < iLen; i++) { | |
68 switch (str[i]) { | |
69 case '&': | |
70 textBuf << FX_WSTRC(L"&"); | |
71 break; | |
72 case '<': | |
73 textBuf << FX_WSTRC(L"<"); | |
74 break; | |
75 case '>': | |
76 textBuf << FX_WSTRC(L">"); | |
77 break; | |
78 case '\'': | |
79 textBuf << FX_WSTRC(L"'"); | |
80 break; | |
81 case '\"': | |
82 textBuf << FX_WSTRC(L"""); | |
83 break; | |
84 default: | |
85 textBuf.AppendChar(str[i]); | |
86 } | |
87 } | |
88 return textBuf.MakeString(); | |
89 } | |
90 CFX_WideString XFA_ExportEncodeContent(const CFX_WideStringC& str) { | |
91 CFX_WideTextBuf textBuf; | |
92 int32_t iLen = str.GetLength(); | |
93 for (int32_t i = 0; i < iLen; i++) { | |
94 FX_WCHAR ch = str.GetAt(i); | |
95 if (!FDE_IsXMLValidChar(ch)) { | |
96 continue; | |
97 } | |
98 if (ch == '&') { | |
99 textBuf << FX_WSTRC(L"&"); | |
100 } else if (ch == '<') { | |
101 textBuf << FX_WSTRC(L"<"); | |
102 } else if (ch == '>') { | |
103 textBuf << FX_WSTRC(L">"); | |
104 } else if (ch == '\'') { | |
105 textBuf << FX_WSTRC(L"'"); | |
106 } else if (ch == '\"') { | |
107 textBuf << FX_WSTRC(L"""); | |
108 } else if (ch == ' ') { | |
109 if (i && str.GetAt(i - 1) != ' ') { | |
110 textBuf.AppendChar(' '); | |
111 } else { | |
112 textBuf << FX_WSTRC(L" "); | |
113 } | |
114 } else { | |
115 textBuf.AppendChar(str.GetAt(i)); | |
116 } | |
117 } | |
118 return textBuf.MakeString(); | |
119 } | |
120 static void XFA_SaveAttribute(CXFA_Node* pNode, | |
121 XFA_ATTRIBUTE eName, | |
122 const CFX_WideStringC& wsName, | |
123 FX_BOOL bProto, | |
124 CFX_WideString& wsOutput) { | |
125 CFX_WideString wsValue; | |
126 if ((!bProto && !pNode->HasAttribute((XFA_ATTRIBUTE)eName, bProto)) || | |
127 !pNode->GetAttribute((XFA_ATTRIBUTE)eName, wsValue, FALSE)) { | |
128 return; | |
129 } | |
130 wsValue = XFA_ExportEncodeAttribute(wsValue); | |
131 wsOutput += FX_WSTRC(L" "); | |
132 wsOutput += wsName; | |
133 wsOutput += FX_WSTRC(L"=\""); | |
134 wsOutput += wsValue; | |
135 wsOutput += FX_WSTRC(L"\""); | |
136 } | |
137 static FX_BOOL XFA_DataExporter_AttributeSaveInDataModel( | |
138 CXFA_Node* pNode, | |
139 XFA_ATTRIBUTE eAttribute) { | |
140 FX_BOOL bSaveInDataModel = FALSE; | |
141 if (pNode->GetElementType() != XFA_Element::Image) { | |
142 return bSaveInDataModel; | |
143 } | |
144 CXFA_Node* pValueNode = pNode->GetNodeItem(XFA_NODEITEM_Parent); | |
145 if (!pValueNode || pValueNode->GetElementType() != XFA_Element::Value) { | |
146 return bSaveInDataModel; | |
147 } | |
148 CXFA_Node* pFieldNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent); | |
149 if (pFieldNode && pFieldNode->GetBindData() && | |
150 eAttribute == XFA_ATTRIBUTE_Href) { | |
151 bSaveInDataModel = TRUE; | |
152 } | |
153 return bSaveInDataModel; | |
154 } | |
155 FX_BOOL XFA_DataExporter_ContentNodeNeedtoExport(CXFA_Node* pContentNode) { | |
156 CFX_WideString wsContent; | |
157 if (!pContentNode->TryContent(wsContent, FALSE, FALSE)) | |
158 return FALSE; | |
159 | |
160 ASSERT(pContentNode->IsContentNode()); | |
161 CXFA_Node* pParentNode = pContentNode->GetNodeItem(XFA_NODEITEM_Parent); | |
162 if (!pParentNode || pParentNode->GetElementType() != XFA_Element::Value) | |
163 return TRUE; | |
164 | |
165 CXFA_Node* pGrandParentNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent); | |
166 if (!pGrandParentNode || !pGrandParentNode->IsContainerNode()) | |
167 return TRUE; | |
168 if (pGrandParentNode->GetBindData()) | |
169 return FALSE; | |
170 | |
171 CXFA_WidgetData* pWidgetData = pGrandParentNode->GetWidgetData(); | |
172 XFA_Element eUIType = pWidgetData->GetUIType(); | |
173 if (eUIType == XFA_Element::PasswordEdit) { | |
174 return FALSE; | |
175 } | |
176 return TRUE; | |
177 } | |
178 static void XFA_DataExporter_RecognizeXFAVersionNumber( | |
179 CXFA_Node* pTemplateRoot, | |
180 CFX_WideString& wsVersionNumber) { | |
181 wsVersionNumber.clear(); | |
182 if (!pTemplateRoot) { | |
183 return; | |
184 } | |
185 CFX_WideString wsTemplateNS; | |
186 if (!pTemplateRoot->TryNamespace(wsTemplateNS)) { | |
187 return; | |
188 } | |
189 XFA_VERSION eVersion = | |
190 pTemplateRoot->GetDocument()->RecognizeXFAVersionNumber(wsTemplateNS); | |
191 if (eVersion == XFA_VERSION_UNKNOWN) { | |
192 eVersion = XFA_VERSION_DEFAULT; | |
193 } | |
194 wsVersionNumber.Format(L"%i.%i", eVersion / 100, eVersion % 100); | |
195 } | |
196 static void XFA_DataExporter_RegenerateFormFile_Changed( | |
197 CXFA_Node* pNode, | |
198 CFX_WideTextBuf& buf, | |
199 FX_BOOL bSaveXML = FALSE) { | |
200 CFX_WideString wsAttrs; | |
201 int32_t iAttrs = 0; | |
202 const uint8_t* pAttrs = | |
203 XFA_GetElementAttributes(pNode->GetElementType(), iAttrs); | |
204 while (iAttrs--) { | |
205 const XFA_ATTRIBUTEINFO* pAttr = | |
206 XFA_GetAttributeByID((XFA_ATTRIBUTE)pAttrs[iAttrs]); | |
207 if (pAttr->eName == XFA_ATTRIBUTE_Name || | |
208 (XFA_DataExporter_AttributeSaveInDataModel(pNode, pAttr->eName) && | |
209 !bSaveXML)) { | |
210 continue; | |
211 } | |
212 CFX_WideString wsAttr; | |
213 XFA_SaveAttribute(pNode, pAttr->eName, pAttr->pName, bSaveXML, wsAttr); | |
214 wsAttrs += wsAttr; | |
215 } | |
216 CFX_WideString wsChildren; | |
217 switch (pNode->GetObjectType()) { | |
218 case XFA_ObjectType::ContentNode: { | |
219 if (!bSaveXML && !XFA_DataExporter_ContentNodeNeedtoExport(pNode)) { | |
220 break; | |
221 } | |
222 CXFA_Node* pRawValueNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
223 while (pRawValueNode && | |
224 pRawValueNode->GetElementType() != XFA_Element::SharpxHTML && | |
225 pRawValueNode->GetElementType() != XFA_Element::Sharptext && | |
226 pRawValueNode->GetElementType() != XFA_Element::Sharpxml) { | |
227 pRawValueNode = pRawValueNode->GetNodeItem(XFA_NODEITEM_NextSibling); | |
228 } | |
229 if (!pRawValueNode) { | |
230 break; | |
231 } | |
232 CFX_WideString wsContentType; | |
233 pNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE); | |
234 if (pRawValueNode->GetElementType() == XFA_Element::SharpxHTML && | |
235 wsContentType == FX_WSTRC(L"text/html")) { | |
236 CFDE_XMLNode* pExDataXML = pNode->GetXMLMappingNode(); | |
237 if (!pExDataXML) { | |
238 break; | |
239 } | |
240 CFDE_XMLNode* pRichTextXML = | |
241 pExDataXML->GetNodeItem(CFDE_XMLNode::FirstChild); | |
242 if (!pRichTextXML) { | |
243 break; | |
244 } | |
245 IFX_MemoryStream* pMemStream = FX_CreateMemoryStream(TRUE); | |
246 IFX_Stream* pTempStream = IFX_Stream::CreateStream( | |
247 (IFX_FileWrite*)pMemStream, FX_STREAMACCESS_Text | | |
248 FX_STREAMACCESS_Write | | |
249 FX_STREAMACCESS_Append); | |
250 pTempStream->SetCodePage(FX_CODEPAGE_UTF8); | |
251 pRichTextXML->SaveXMLNode(pTempStream); | |
252 wsChildren += CFX_WideString::FromUTF8( | |
253 CFX_ByteStringC(pMemStream->GetBuffer(), pMemStream->GetSize())); | |
254 pTempStream->Release(); | |
255 pMemStream->Release(); | |
256 } else if (pRawValueNode->GetElementType() == XFA_Element::Sharpxml && | |
257 wsContentType == FX_WSTRC(L"text/xml")) { | |
258 CFX_WideString wsRawValue; | |
259 pRawValueNode->GetAttribute(XFA_ATTRIBUTE_Value, wsRawValue, FALSE); | |
260 if (wsRawValue.IsEmpty()) { | |
261 break; | |
262 } | |
263 CFX_WideStringArray wsSelTextArray; | |
264 int32_t iStart = 0; | |
265 int32_t iEnd = wsRawValue.Find(L'\n', iStart); | |
266 iEnd = (iEnd == -1) ? wsRawValue.GetLength() : iEnd; | |
267 while (iEnd >= iStart) { | |
268 wsSelTextArray.Add(wsRawValue.Mid(iStart, iEnd - iStart)); | |
269 iStart = iEnd + 1; | |
270 if (iStart >= wsRawValue.GetLength()) { | |
271 break; | |
272 } | |
273 iEnd = wsRawValue.Find(L'\n', iStart); | |
274 } | |
275 CXFA_Node* pParentNode = pNode->GetNodeItem(XFA_NODEITEM_Parent); | |
276 ASSERT(pParentNode); | |
277 CXFA_Node* pGrandparentNode = | |
278 pParentNode->GetNodeItem(XFA_NODEITEM_Parent); | |
279 ASSERT(pGrandparentNode); | |
280 CFX_WideString bodyTagName; | |
281 bodyTagName = pGrandparentNode->GetCData(XFA_ATTRIBUTE_Name); | |
282 if (bodyTagName.IsEmpty()) { | |
283 bodyTagName = FX_WSTRC(L"ListBox1"); | |
284 } | |
285 buf << FX_WSTRC(L"<"); | |
286 buf << bodyTagName; | |
287 buf << FX_WSTRC(L" xmlns=\"\"\n>"); | |
288 for (int32_t i = 0; i < wsSelTextArray.GetSize(); i++) { | |
289 buf << FX_WSTRC(L"<value\n>"); | |
290 buf << XFA_ExportEncodeContent(wsSelTextArray[i].AsStringC()); | |
291 buf << FX_WSTRC(L"</value\n>"); | |
292 } | |
293 buf << FX_WSTRC(L"</"); | |
294 buf << bodyTagName; | |
295 buf << FX_WSTRC(L"\n>"); | |
296 wsChildren += buf.AsStringC(); | |
297 buf.Clear(); | |
298 } else { | |
299 CFX_WideStringC wsValue = pRawValueNode->GetCData(XFA_ATTRIBUTE_Value); | |
300 wsChildren += XFA_ExportEncodeContent(wsValue); | |
301 } | |
302 } break; | |
303 case XFA_ObjectType::TextNode: | |
304 case XFA_ObjectType::NodeC: | |
305 case XFA_ObjectType::NodeV: { | |
306 CFX_WideStringC wsValue = pNode->GetCData(XFA_ATTRIBUTE_Value); | |
307 wsChildren += XFA_ExportEncodeContent(wsValue); | |
308 } break; | |
309 default: | |
310 if (pNode->GetElementType() == XFA_Element::Items) { | |
311 CXFA_Node* pTemplateNode = pNode->GetTemplateNode(); | |
312 if (!pTemplateNode || | |
313 pTemplateNode->CountChildren(XFA_Element::Unknown) != | |
314 pNode->CountChildren(XFA_Element::Unknown)) { | |
315 bSaveXML = TRUE; | |
316 } | |
317 } | |
318 CFX_WideTextBuf newBuf; | |
319 CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
320 while (pChildNode) { | |
321 XFA_DataExporter_RegenerateFormFile_Changed(pChildNode, newBuf, | |
322 bSaveXML); | |
323 wsChildren += newBuf.AsStringC(); | |
324 newBuf.Clear(); | |
325 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling); | |
326 } | |
327 if (!bSaveXML && !wsChildren.IsEmpty() && | |
328 pNode->GetElementType() == XFA_Element::Items) { | |
329 wsChildren.clear(); | |
330 bSaveXML = TRUE; | |
331 CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
332 while (pChild) { | |
333 XFA_DataExporter_RegenerateFormFile_Changed(pChild, newBuf, bSaveXML); | |
334 wsChildren += newBuf.AsStringC(); | |
335 newBuf.Clear(); | |
336 pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling); | |
337 } | |
338 } | |
339 break; | |
340 } | |
341 if (!wsChildren.IsEmpty() || !wsAttrs.IsEmpty() || | |
342 pNode->HasAttribute(XFA_ATTRIBUTE_Name)) { | |
343 CFX_WideStringC wsElement = pNode->GetClassName(); | |
344 CFX_WideString wsName; | |
345 XFA_SaveAttribute(pNode, XFA_ATTRIBUTE_Name, FX_WSTRC(L"name"), TRUE, | |
346 wsName); | |
347 buf << FX_WSTRC(L"<"); | |
348 buf << wsElement; | |
349 buf << wsName; | |
350 buf << wsAttrs; | |
351 if (wsChildren.IsEmpty()) { | |
352 buf << FX_WSTRC(L"\n/>"); | |
353 } else { | |
354 buf << FX_WSTRC(L"\n>"); | |
355 buf << wsChildren; | |
356 buf << FX_WSTRC(L"</"); | |
357 buf << wsElement; | |
358 buf << FX_WSTRC(L"\n>"); | |
359 } | |
360 } | |
361 } | |
362 static void XFA_DataExporter_RegenerateFormFile_Container( | |
363 CXFA_Node* pNode, | |
364 IFX_Stream* pStream, | |
365 FX_BOOL bSaveXML = FALSE) { | |
366 XFA_Element eType = pNode->GetElementType(); | |
367 if (eType == XFA_Element::Field || eType == XFA_Element::Draw || | |
368 !pNode->IsContainerNode()) { | |
369 CFX_WideTextBuf buf; | |
370 XFA_DataExporter_RegenerateFormFile_Changed(pNode, buf, bSaveXML); | |
371 FX_STRSIZE nLen = buf.GetLength(); | |
372 if (nLen > 0) { | |
373 pStream->WriteString((const FX_WCHAR*)buf.GetBuffer(), nLen); | |
374 } | |
375 return; | |
376 } | |
377 CFX_WideStringC wsElement = pNode->GetClassName(); | |
378 pStream->WriteString(L"<", 1); | |
379 pStream->WriteString(wsElement.c_str(), wsElement.GetLength()); | |
380 CFX_WideString wsOutput; | |
381 XFA_SaveAttribute(pNode, XFA_ATTRIBUTE_Name, FX_WSTRC(L"name"), TRUE, | |
382 wsOutput); | |
383 CFX_WideString wsAttrs; | |
384 int32_t iAttrs = 0; | |
385 const uint8_t* pAttrs = | |
386 XFA_GetElementAttributes(pNode->GetElementType(), iAttrs); | |
387 while (iAttrs--) { | |
388 const XFA_ATTRIBUTEINFO* pAttr = | |
389 XFA_GetAttributeByID((XFA_ATTRIBUTE)pAttrs[iAttrs]); | |
390 if (pAttr->eName == XFA_ATTRIBUTE_Name) { | |
391 continue; | |
392 } | |
393 CFX_WideString wsAttr; | |
394 XFA_SaveAttribute(pNode, pAttr->eName, pAttr->pName, FALSE, wsAttr); | |
395 wsOutput += wsAttr; | |
396 } | |
397 if (!wsOutput.IsEmpty()) { | |
398 pStream->WriteString(wsOutput.c_str(), wsOutput.GetLength()); | |
399 } | |
400 CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
401 if (pChildNode) { | |
402 pStream->WriteString(L"\n>", 2); | |
403 while (pChildNode) { | |
404 XFA_DataExporter_RegenerateFormFile_Container(pChildNode, pStream, | |
405 bSaveXML); | |
406 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling); | |
407 } | |
408 pStream->WriteString(L"</", 2); | |
409 pStream->WriteString(wsElement.c_str(), wsElement.GetLength()); | |
410 pStream->WriteString(L"\n>", 2); | |
411 } else { | |
412 pStream->WriteString(L"\n/>", 3); | |
413 } | |
414 } | |
415 void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode, | |
416 IFX_Stream* pStream, | |
417 const FX_CHAR* pChecksum, | |
418 FX_BOOL bSaveXML) { | |
419 if (pNode->IsModelNode()) { | |
420 static const FX_WCHAR s_pwsTagName[] = L"<form"; | |
421 static const FX_WCHAR s_pwsClose[] = L"</form\n>"; | |
422 pStream->WriteString(s_pwsTagName, FXSYS_wcslen(s_pwsTagName)); | |
423 if (pChecksum) { | |
424 static const FX_WCHAR s_pwChecksum[] = L" checksum=\""; | |
425 CFX_WideString wsChecksum = CFX_WideString::FromUTF8(pChecksum); | |
426 pStream->WriteString(s_pwChecksum, FXSYS_wcslen(s_pwChecksum)); | |
427 pStream->WriteString(wsChecksum.c_str(), wsChecksum.GetLength()); | |
428 pStream->WriteString(L"\"", 1); | |
429 } | |
430 pStream->WriteString(L" xmlns=\"", FXSYS_wcslen(L" xmlns=\"")); | |
431 const FX_WCHAR* pURI = XFA_GetPacketByIndex(XFA_PACKET_Form)->pURI; | |
432 pStream->WriteString(pURI, FXSYS_wcslen(pURI)); | |
433 CFX_WideString wsVersionNumber; | |
434 XFA_DataExporter_RecognizeXFAVersionNumber( | |
435 ToNode(pNode->GetDocument()->GetXFAObject(XFA_HASHCODE_Template)), | |
436 wsVersionNumber); | |
437 if (wsVersionNumber.IsEmpty()) { | |
438 wsVersionNumber = FX_WSTRC(L"2.8"); | |
439 } | |
440 wsVersionNumber += FX_WSTRC(L"/\"\n>"); | |
441 pStream->WriteString(wsVersionNumber.c_str(), wsVersionNumber.GetLength()); | |
442 CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
443 while (pChildNode) { | |
444 XFA_DataExporter_RegenerateFormFile_Container(pChildNode, pStream); | |
445 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling); | |
446 } | |
447 pStream->WriteString(s_pwsClose, FXSYS_wcslen(s_pwsClose)); | |
448 } else { | |
449 XFA_DataExporter_RegenerateFormFile_Container(pNode, pStream, bSaveXML); | |
450 } | |
451 } | |
452 | |
453 CXFA_DataExporter::CXFA_DataExporter(CXFA_Document* pDocument) | |
454 : m_pDocument(pDocument) { | |
455 ASSERT(m_pDocument); | |
456 } | |
457 FX_BOOL CXFA_DataExporter::Export(IFX_FileWrite* pWrite) { | |
458 return Export(pWrite, m_pDocument->GetRoot()); | |
459 } | |
460 FX_BOOL CXFA_DataExporter::Export(IFX_FileWrite* pWrite, | |
461 CXFA_Node* pNode, | |
462 uint32_t dwFlag, | |
463 const FX_CHAR* pChecksum) { | |
464 if (!pWrite) { | |
465 ASSERT(false); | |
466 return FALSE; | |
467 } | |
468 IFX_Stream* pStream = IFX_Stream::CreateStream( | |
469 pWrite, | |
470 FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append); | |
471 if (!pStream) { | |
472 return FALSE; | |
473 } | |
474 pStream->SetCodePage(FX_CODEPAGE_UTF8); | |
475 FX_BOOL bRet = Export(pStream, pNode, dwFlag, pChecksum); | |
476 pStream->Release(); | |
477 return bRet; | |
478 } | |
479 FX_BOOL CXFA_DataExporter::Export(IFX_Stream* pStream, | |
480 CXFA_Node* pNode, | |
481 uint32_t dwFlag, | |
482 const FX_CHAR* pChecksum) { | |
483 CFDE_XMLDoc* pXMLDoc = m_pDocument->GetXMLDoc(); | |
484 if (pNode->IsModelNode()) { | |
485 switch (pNode->GetPacketID()) { | |
486 case XFA_XDPPACKET_XDP: { | |
487 static const FX_WCHAR s_pwsPreamble[] = | |
488 L"<xdp:xdp xmlns:xdp=\"http://ns.adobe.com/xdp/\">"; | |
489 pStream->WriteString(s_pwsPreamble, FXSYS_wcslen(s_pwsPreamble)); | |
490 for (CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
491 pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
492 Export(pStream, pChild, dwFlag, pChecksum); | |
493 } | |
494 static const FX_WCHAR s_pwsPostamble[] = L"</xdp:xdp\n>"; | |
495 pStream->WriteString(s_pwsPostamble, FXSYS_wcslen(s_pwsPostamble)); | |
496 } break; | |
497 case XFA_XDPPACKET_Datasets: { | |
498 CFDE_XMLElement* pElement = | |
499 static_cast<CFDE_XMLElement*>(pNode->GetXMLMappingNode()); | |
500 if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) { | |
501 return FALSE; | |
502 } | |
503 CXFA_Node* pDataNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
504 ASSERT(pDataNode); | |
505 XFA_DataExporter_DealWithDataGroupNode(pDataNode); | |
506 pXMLDoc->SaveXMLNode(pStream, pElement); | |
507 } break; | |
508 case XFA_XDPPACKET_Form: { | |
509 XFA_DataExporter_RegenerateFormFile(pNode, pStream, pChecksum); | |
510 } break; | |
511 case XFA_XDPPACKET_Template: | |
512 default: { | |
513 CFDE_XMLElement* pElement = | |
514 static_cast<CFDE_XMLElement*>(pNode->GetXMLMappingNode()); | |
515 if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) { | |
516 return FALSE; | |
517 } | |
518 pXMLDoc->SaveXMLNode(pStream, pElement); | |
519 } break; | |
520 } | |
521 } else { | |
522 CXFA_Node* pDataNode = pNode->GetNodeItem(XFA_NODEITEM_Parent); | |
523 CXFA_Node* pExportNode = pNode; | |
524 for (CXFA_Node* pChildNode = | |
525 pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
526 pChildNode; | |
527 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
528 if (pChildNode != pNode) { | |
529 pExportNode = pDataNode; | |
530 break; | |
531 } | |
532 } | |
533 CFDE_XMLElement* pElement = | |
534 static_cast<CFDE_XMLElement*>(pExportNode->GetXMLMappingNode()); | |
535 if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) { | |
536 return FALSE; | |
537 } | |
538 XFA_DataExporter_DealWithDataGroupNode(pExportNode); | |
539 pElement->SetString(L"xmlns:xfa", | |
540 L"http://www.xfa.org/schema/xfa-data/1.0/"); | |
541 pXMLDoc->SaveXMLNode(pStream, pElement); | |
542 pElement->RemoveAttribute(L"xmlns:xfa"); | |
543 } | |
544 return TRUE; | |
545 } | |
546 void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node* pDataNode) { | |
547 if (!pDataNode || pDataNode->GetElementType() == XFA_Element::DataValue) { | |
548 return; | |
549 } | |
550 int32_t iChildNum = 0; | |
551 for (CXFA_Node* pChildNode = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild); | |
552 pChildNode; | |
553 pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) { | |
554 iChildNum++; | |
555 XFA_DataExporter_DealWithDataGroupNode(pChildNode); | |
556 } | |
557 if (pDataNode->GetElementType() == XFA_Element::DataGroup) { | |
558 if (iChildNum > 0) { | |
559 CFDE_XMLNode* pXMLNode = pDataNode->GetXMLMappingNode(); | |
560 ASSERT(pXMLNode->GetType() == FDE_XMLNODE_Element); | |
561 CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode); | |
562 if (pXMLElement->HasAttribute(L"xfa:dataNode")) { | |
563 pXMLElement->RemoveAttribute(L"xfa:dataNode"); | |
564 } | |
565 } else { | |
566 CFDE_XMLNode* pXMLNode = pDataNode->GetXMLMappingNode(); | |
567 ASSERT(pXMLNode->GetType() == FDE_XMLNODE_Element); | |
568 static_cast<CFDE_XMLElement*>(pXMLNode)->SetString(L"xfa:dataNode", | |
569 L"dataGroup"); | |
570 } | |
571 } | |
572 } | |
OLD | NEW |