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