// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa/fxfa/parser/xfa_document_serialize.h"

#include "xfa/fde/xml/fde_xml_imp.h"
#include "xfa/fgas/crt/fgas_codepage.h"
#include "xfa/fxfa/fm2js/xfa_fm2jsapi.h"
#include "xfa/fxfa/parser/xfa_doclayout.h"
#include "xfa/fxfa/parser/xfa_document.h"
#include "xfa/fxfa/parser/xfa_localemgr.h"
#include "xfa/fxfa/parser/xfa_object.h"
#include "xfa/fxfa/parser/xfa_parser.h"
#include "xfa/fxfa/parser/xfa_parser_imp.h"
#include "xfa/fxfa/parser/xfa_script.h"
#include "xfa/fxfa/parser/xfa_utils.h"

CXFA_DataImporter::CXFA_DataImporter(CXFA_Document* pDocument)
    : m_pDocument(pDocument) {
  ASSERT(m_pDocument);
}
FX_BOOL CXFA_DataImporter::ImportData(IFX_FileRead* pDataDocument) {
  IXFA_Parser* pDataDocumentParser = IXFA_Parser::Create(m_pDocument);
  if (!pDataDocumentParser) {
    return FALSE;
  }
  if (pDataDocumentParser->StartParse(pDataDocument, XFA_XDPPACKET_Datasets) !=
      XFA_PARSESTATUS_Ready) {
    pDataDocumentParser->Release();
    return FALSE;
  }
  if (pDataDocumentParser->DoParse(NULL) < XFA_PARSESTATUS_Done) {
    pDataDocumentParser->Release();
    return FALSE;
  }
  CXFA_Node* pImportDataRoot = pDataDocumentParser->GetRootNode();
  if (!pImportDataRoot) {
    pDataDocumentParser->Release();
    return FALSE;
  }
  CXFA_Node* pDataModel =
      ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Datasets));
  if (!pDataModel) {
    pDataDocumentParser->Release();
    return FALSE;
  }
  CXFA_Node* pDataNode = ToNode(m_pDocument->GetXFAObject(XFA_HASHCODE_Data));
  if (pDataNode) {
    pDataModel->RemoveChild(pDataNode);
  }
  if (pImportDataRoot->GetClassID() == XFA_ELEMENT_DataModel) {
    while (CXFA_Node* pChildNode =
               pImportDataRoot->GetNodeItem(XFA_NODEITEM_FirstChild)) {
      pImportDataRoot->RemoveChild(pChildNode);
      pDataModel->InsertChild(pChildNode);
    }
  } else {
    CFDE_XMLNode* pXMLNode = pImportDataRoot->GetXMLMappingNode();
    CFDE_XMLNode* pParentXMLNode = pXMLNode->GetNodeItem(CFDE_XMLNode::Parent);
    if (pParentXMLNode) {
      pParentXMLNode->RemoveChildNode(pXMLNode);
    }
    pDataModel->InsertChild(pImportDataRoot);
  }
  m_pDocument->DoDataRemerge(FALSE);
  pDataDocumentParser->Release();
  return TRUE;
}
CFX_WideString XFA_ExportEncodeAttribute(const CFX_WideString& str) {
  CFX_WideTextBuf textBuf;
  int32_t iLen = str.GetLength();
  for (int32_t i = 0; i < iLen; i++) {
    switch (str[i]) {
      case '&':
        textBuf << FX_WSTRC(L"&amp;");
        break;
      case '<':
        textBuf << FX_WSTRC(L"&lt;");
        break;
      case '>':
        textBuf << FX_WSTRC(L"&gt;");
        break;
      case '\'':
        textBuf << FX_WSTRC(L"&apos;");
        break;
      case '\"':
        textBuf << FX_WSTRC(L"&quot;");
        break;
      default:
        textBuf.AppendChar(str[i]);
    }
  }
  return textBuf.MakeString();
}
CFX_WideString XFA_ExportEncodeContent(const CFX_WideStringC& str) {
  CFX_WideTextBuf textBuf;
  int32_t iLen = str.GetLength();
  for (int32_t i = 0; i < iLen; i++) {
    FX_WCHAR ch = str.GetAt(i);
    if (!FDE_IsXMLValidChar(ch)) {
      continue;
    }
    if (ch == '&') {
      textBuf << FX_WSTRC(L"&amp;");
    } else if (ch == '<') {
      textBuf << FX_WSTRC(L"&lt;");
    } else if (ch == '>') {
      textBuf << FX_WSTRC(L"&gt;");
    } else if (ch == '\'') {
      textBuf << FX_WSTRC(L"&apos;");
    } else if (ch == '\"') {
      textBuf << FX_WSTRC(L"&quot;");
    } else if (ch == ' ') {
      if (i && str.GetAt(i - 1) != ' ') {
        textBuf.AppendChar(' ');
      } else {
        textBuf << FX_WSTRC(L"&#x20;");
      }
    } else {
      textBuf.AppendChar(str.GetAt(i));
    }
  }
  return textBuf.MakeString();
}
static void XFA_SaveAttribute(CXFA_Node* pNode,
                              XFA_ATTRIBUTE eName,
                              const CFX_WideStringC& wsName,
                              FX_BOOL bProto,
                              CFX_WideString& wsOutput) {
  CFX_WideString wsValue;
  if ((!bProto && !pNode->HasAttribute((XFA_ATTRIBUTE)eName, bProto)) ||
      !pNode->GetAttribute((XFA_ATTRIBUTE)eName, wsValue, FALSE)) {
    return;
  }
  wsValue = XFA_ExportEncodeAttribute(wsValue);
  wsOutput += FX_WSTRC(L" ");
  wsOutput += wsName;
  wsOutput += FX_WSTRC(L"=\"");
  wsOutput += wsValue;
  wsOutput += FX_WSTRC(L"\"");
}
static FX_BOOL XFA_DataExporter_AttributeSaveInDataModel(
    CXFA_Node* pNode,
    XFA_ATTRIBUTE eAttribute) {
  FX_BOOL bSaveInDataModel = FALSE;
  if (pNode->GetClassID() != XFA_ELEMENT_Image) {
    return bSaveInDataModel;
  }
  CXFA_Node* pValueNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
  if (!pValueNode || pValueNode->GetClassID() != XFA_ELEMENT_Value) {
    return bSaveInDataModel;
  }
  CXFA_Node* pFieldNode = pValueNode->GetNodeItem(XFA_NODEITEM_Parent);
  if (pFieldNode && pFieldNode->GetBindData() &&
      eAttribute == XFA_ATTRIBUTE_Href) {
    bSaveInDataModel = TRUE;
  }
  return bSaveInDataModel;
}
FX_BOOL XFA_DataExporter_ContentNodeNeedtoExport(CXFA_Node* pContentNode) {
  CFX_WideString wsContent;
  if (!pContentNode->TryContent(wsContent, FALSE, FALSE)) {
    return FALSE;
  }
  ASSERT(pContentNode->GetObjectType() == XFA_OBJECTTYPE_ContentNode);
  CXFA_Node* pParentNode = pContentNode->GetNodeItem(XFA_NODEITEM_Parent);
  if (!pParentNode || pParentNode->GetClassID() != XFA_ELEMENT_Value) {
    return TRUE;
  }
  CXFA_Node* pGrandParentNode = pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
  if (!pGrandParentNode ||
      pGrandParentNode->GetObjectType() != XFA_OBJECTTYPE_ContainerNode) {
    return TRUE;
  }
  if (pGrandParentNode->GetBindData()) {
    return FALSE;
  }
  CXFA_WidgetData* pWidgetData = pGrandParentNode->GetWidgetData();
  XFA_ELEMENT eUIType = pWidgetData->GetUIType();
  if (eUIType == XFA_ELEMENT_PasswordEdit) {
    return FALSE;
  }
  return TRUE;
}
static void XFA_DataExporter_RecognizeXFAVersionNumber(
    CXFA_Node* pTemplateRoot,
    CFX_WideString& wsVersionNumber) {
  wsVersionNumber.clear();
  if (!pTemplateRoot) {
    return;
  }
  CFX_WideString wsTemplateNS;
  if (!pTemplateRoot->TryNamespace(wsTemplateNS)) {
    return;
  }
  XFA_VERSION eVersion =
      pTemplateRoot->GetDocument()->RecognizeXFAVersionNumber(wsTemplateNS);
  if (eVersion == XFA_VERSION_UNKNOWN) {
    eVersion = XFA_VERSION_DEFAULT;
  }
  wsVersionNumber.Format(L"%i.%i", eVersion / 100, eVersion % 100);
}
static void XFA_DataExporter_RegenerateFormFile_Changed(
    CXFA_Node* pNode,
    CFX_WideTextBuf& buf,
    FX_BOOL bSaveXML = FALSE) {
  CFX_WideString wsAttrs;
  int32_t iAttrs = 0;
  const uint8_t* pAttrs = XFA_GetElementAttributes(pNode->GetClassID(), iAttrs);
  while (iAttrs--) {
    const XFA_ATTRIBUTEINFO* pAttr =
        XFA_GetAttributeByID((XFA_ATTRIBUTE)pAttrs[iAttrs]);
    if (pAttr->eName == XFA_ATTRIBUTE_Name ||
        (XFA_DataExporter_AttributeSaveInDataModel(pNode, pAttr->eName) &&
         !bSaveXML)) {
      continue;
    }
    CFX_WideString wsAttr;
    XFA_SaveAttribute(pNode, pAttr->eName, pAttr->pName, bSaveXML, wsAttr);
    wsAttrs += wsAttr;
  }
  CFX_WideString wsChildren;
  switch (pNode->GetObjectType()) {
    case XFA_OBJECTTYPE_ContentNode: {
      if (!bSaveXML && !XFA_DataExporter_ContentNodeNeedtoExport(pNode)) {
        break;
      }
      CXFA_Node* pRawValueNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
      while (pRawValueNode &&
             pRawValueNode->GetClassID() != XFA_ELEMENT_SharpxHTML &&
             pRawValueNode->GetClassID() != XFA_ELEMENT_Sharptext &&
             pRawValueNode->GetClassID() != XFA_ELEMENT_Sharpxml) {
        pRawValueNode = pRawValueNode->GetNodeItem(XFA_NODEITEM_NextSibling);
      }
      if (!pRawValueNode) {
        break;
      }
      CFX_WideString wsContentType;
      pNode->GetAttribute(XFA_ATTRIBUTE_ContentType, wsContentType, FALSE);
      if (pRawValueNode->GetClassID() == XFA_ELEMENT_SharpxHTML &&
          wsContentType == FX_WSTRC(L"text/html")) {
        CFDE_XMLNode* pExDataXML = pNode->GetXMLMappingNode();
        if (!pExDataXML) {
          break;
        }
        CFDE_XMLNode* pRichTextXML =
            pExDataXML->GetNodeItem(CFDE_XMLNode::FirstChild);
        if (!pRichTextXML) {
          break;
        }
        IFX_MemoryStream* pMemStream = FX_CreateMemoryStream(TRUE);
        IFX_Stream* pTempStream = IFX_Stream::CreateStream(
            (IFX_FileWrite*)pMemStream, FX_STREAMACCESS_Text |
                                            FX_STREAMACCESS_Write |
                                            FX_STREAMACCESS_Append);
        pTempStream->SetCodePage(FX_CODEPAGE_UTF8);
        pRichTextXML->SaveXMLNode(pTempStream);
        wsChildren += CFX_WideString::FromUTF8(
            CFX_ByteStringC(pMemStream->GetBuffer(), pMemStream->GetSize()));
        pTempStream->Release();
        pMemStream->Release();
      } else if (pRawValueNode->GetClassID() == XFA_ELEMENT_Sharpxml &&
                 wsContentType == FX_WSTRC(L"text/xml")) {
        CFX_WideString wsRawValue;
        pRawValueNode->GetAttribute(XFA_ATTRIBUTE_Value, wsRawValue, FALSE);
        if (wsRawValue.IsEmpty()) {
          break;
        }
        CFX_WideStringArray wsSelTextArray;
        int32_t iStart = 0;
        int32_t iEnd = wsRawValue.Find(L'\n', iStart);
        iEnd = (iEnd == -1) ? wsRawValue.GetLength() : iEnd;
        while (iEnd >= iStart) {
          wsSelTextArray.Add(wsRawValue.Mid(iStart, iEnd - iStart));
          iStart = iEnd + 1;
          if (iStart >= wsRawValue.GetLength()) {
            break;
          }
          iEnd = wsRawValue.Find(L'\n', iStart);
        }
        CXFA_Node* pParentNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
        ASSERT(pParentNode);
        CXFA_Node* pGrandparentNode =
            pParentNode->GetNodeItem(XFA_NODEITEM_Parent);
        ASSERT(pGrandparentNode);
        CFX_WideString bodyTagName;
        bodyTagName = pGrandparentNode->GetCData(XFA_ATTRIBUTE_Name);
        if (bodyTagName.IsEmpty()) {
          bodyTagName = FX_WSTRC(L"ListBox1");
        }
        buf << FX_WSTRC(L"<");
        buf << bodyTagName;
        buf << FX_WSTRC(L" xmlns=\"\"\n>");
        for (int32_t i = 0; i < wsSelTextArray.GetSize(); i++) {
          buf << FX_WSTRC(L"<value\n>");
          buf << XFA_ExportEncodeContent(wsSelTextArray[i].AsStringC());
          buf << FX_WSTRC(L"</value\n>");
        }
        buf << FX_WSTRC(L"</");
        buf << bodyTagName;
        buf << FX_WSTRC(L"\n>");
        wsChildren += buf.AsStringC();
        buf.Clear();
      } else {
        CFX_WideStringC wsValue = pRawValueNode->GetCData(XFA_ATTRIBUTE_Value);
        wsChildren += XFA_ExportEncodeContent(wsValue);
      }
    } break;
    case XFA_OBJECTTYPE_TextNode:
    case XFA_OBJECTTYPE_NodeC:
    case XFA_OBJECTTYPE_NodeV: {
      CFX_WideStringC wsValue = pNode->GetCData(XFA_ATTRIBUTE_Value);
      wsChildren += XFA_ExportEncodeContent(wsValue);
    } break;
    default:
      if (pNode->GetClassID() == XFA_ELEMENT_Items) {
        CXFA_Node* pTemplateNode = pNode->GetTemplateNode();
        if (!pTemplateNode ||
            pTemplateNode->CountChildren(XFA_ELEMENT_UNKNOWN) !=
                pNode->CountChildren(XFA_ELEMENT_UNKNOWN)) {
          bSaveXML = TRUE;
        }
      }
      CFX_WideTextBuf newBuf;
      CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
      while (pChildNode) {
        XFA_DataExporter_RegenerateFormFile_Changed(pChildNode, newBuf,
                                                    bSaveXML);
        wsChildren += newBuf.AsStringC();
        newBuf.Clear();
        pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
      }
      if (!bSaveXML && !wsChildren.IsEmpty() &&
          pNode->GetClassID() == XFA_ELEMENT_Items) {
        wsChildren.clear();
        bSaveXML = TRUE;
        CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
        while (pChildNode) {
          XFA_DataExporter_RegenerateFormFile_Changed(pChildNode, newBuf,
                                                      bSaveXML);
          wsChildren += newBuf.AsStringC();
          newBuf.Clear();
          pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
        }
      }
      break;
  }
  if (!wsChildren.IsEmpty() || !wsAttrs.IsEmpty() ||
      pNode->HasAttribute(XFA_ATTRIBUTE_Name)) {
    CFX_WideStringC wsElement;
    pNode->GetClassName(wsElement);
    CFX_WideString wsName;
    XFA_SaveAttribute(pNode, XFA_ATTRIBUTE_Name, FX_WSTRC(L"name"), TRUE,
                      wsName);
    buf << FX_WSTRC(L"<");
    buf << wsElement;
    buf << wsName;
    buf << wsAttrs;
    if (wsChildren.IsEmpty()) {
      buf << FX_WSTRC(L"\n/>");
    } else {
      buf << FX_WSTRC(L"\n>");
      buf << wsChildren;
      buf << FX_WSTRC(L"</");
      buf << wsElement;
      buf << FX_WSTRC(L"\n>");
    }
  }
}
static void XFA_DataExporter_RegenerateFormFile_Container(
    CXFA_Node* pNode,
    IFX_Stream* pStream,
    FX_BOOL bSaveXML = FALSE) {
  XFA_ELEMENT eElement = pNode->GetClassID();
  if (eElement == XFA_ELEMENT_Field || eElement == XFA_ELEMENT_Draw ||
      !pNode->IsContainerNode()) {
    CFX_WideTextBuf buf;
    XFA_DataExporter_RegenerateFormFile_Changed(pNode, buf, bSaveXML);
    FX_STRSIZE nLen = buf.GetLength();
    if (nLen > 0) {
      pStream->WriteString((const FX_WCHAR*)buf.GetBuffer(), nLen);
    }
    return;
  }
  CFX_WideStringC wsElement;
  pNode->GetClassName(wsElement);
  pStream->WriteString(L"<", 1);
  pStream->WriteString(wsElement.c_str(), wsElement.GetLength());
  CFX_WideString wsOutput;
  XFA_SaveAttribute(pNode, XFA_ATTRIBUTE_Name, FX_WSTRC(L"name"), TRUE,
                    wsOutput);
  CFX_WideString wsAttrs;
  int32_t iAttrs = 0;
  const uint8_t* pAttrs = XFA_GetElementAttributes(pNode->GetClassID(), iAttrs);
  while (iAttrs--) {
    const XFA_ATTRIBUTEINFO* pAttr =
        XFA_GetAttributeByID((XFA_ATTRIBUTE)pAttrs[iAttrs]);
    if (pAttr->eName == XFA_ATTRIBUTE_Name) {
      continue;
    }
    CFX_WideString wsAttr;
    XFA_SaveAttribute(pNode, pAttr->eName, pAttr->pName, FALSE, wsAttr);
    wsOutput += wsAttr;
  }
  if (!wsOutput.IsEmpty()) {
    pStream->WriteString(wsOutput.c_str(), wsOutput.GetLength());
  }
  CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
  if (pChildNode) {
    pStream->WriteString(L"\n>", 2);
    while (pChildNode) {
      XFA_DataExporter_RegenerateFormFile_Container(pChildNode, pStream,
                                                    bSaveXML);
      pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
    pStream->WriteString(L"</", 2);
    pStream->WriteString(wsElement.c_str(), wsElement.GetLength());
    pStream->WriteString(L"\n>", 2);
  } else {
    pStream->WriteString(L"\n/>", 3);
  }
}
void XFA_DataExporter_RegenerateFormFile(CXFA_Node* pNode,
                                         IFX_Stream* pStream,
                                         const FX_CHAR* pChecksum,
                                         FX_BOOL bSaveXML) {
  if (pNode->GetObjectType() == XFA_OBJECTTYPE_ModelNode) {
    static const FX_WCHAR s_pwsTagName[] = L"<form";
    static const FX_WCHAR s_pwsClose[] = L"</form\n>";
    pStream->WriteString(s_pwsTagName, FXSYS_wcslen(s_pwsTagName));
    if (pChecksum) {
      static const FX_WCHAR s_pwChecksum[] = L" checksum=\"";
      CFX_WideString wsChecksum = CFX_WideString::FromUTF8(pChecksum);
      pStream->WriteString(s_pwChecksum, FXSYS_wcslen(s_pwChecksum));
      pStream->WriteString(wsChecksum.c_str(), wsChecksum.GetLength());
      pStream->WriteString(L"\"", 1);
    }
    pStream->WriteString(L" xmlns=\"", FXSYS_wcslen(L" xmlns=\""));
    const FX_WCHAR* pURI = XFA_GetPacketByIndex(XFA_PACKET_Form)->pURI;
    pStream->WriteString(pURI, FXSYS_wcslen(pURI));
    CFX_WideString wsVersionNumber;
    XFA_DataExporter_RecognizeXFAVersionNumber(
        ToNode(pNode->GetDocument()->GetXFAObject(XFA_HASHCODE_Template)),
        wsVersionNumber);
    if (wsVersionNumber.IsEmpty()) {
      wsVersionNumber = FX_WSTRC(L"2.8");
    }
    wsVersionNumber += FX_WSTRC(L"/\"\n>");
    pStream->WriteString(wsVersionNumber.c_str(), wsVersionNumber.GetLength());
    CXFA_Node* pChildNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
    while (pChildNode) {
      XFA_DataExporter_RegenerateFormFile_Container(pChildNode, pStream);
      pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
    }
    pStream->WriteString(s_pwsClose, FXSYS_wcslen(s_pwsClose));
  } else {
    XFA_DataExporter_RegenerateFormFile_Container(pNode, pStream, bSaveXML);
  }
}

CXFA_DataExporter::CXFA_DataExporter(CXFA_Document* pDocument)
    : m_pDocument(pDocument) {
  ASSERT(m_pDocument);
}
FX_BOOL CXFA_DataExporter::Export(IFX_FileWrite* pWrite) {
  return Export(pWrite, m_pDocument->GetRoot());
}
FX_BOOL CXFA_DataExporter::Export(IFX_FileWrite* pWrite,
                                  CXFA_Node* pNode,
                                  uint32_t dwFlag,
                                  const FX_CHAR* pChecksum) {
  if (!pWrite) {
    ASSERT(false);
    return FALSE;
  }
  IFX_Stream* pStream = IFX_Stream::CreateStream(
      pWrite,
      FX_STREAMACCESS_Text | FX_STREAMACCESS_Write | FX_STREAMACCESS_Append);
  if (pStream == NULL) {
    return FALSE;
  }
  pStream->SetCodePage(FX_CODEPAGE_UTF8);
  FX_BOOL bRet = Export(pStream, pNode, dwFlag, pChecksum);
  pStream->Release();
  return bRet;
}
FX_BOOL CXFA_DataExporter::Export(IFX_Stream* pStream,
                                  CXFA_Node* pNode,
                                  uint32_t dwFlag,
                                  const FX_CHAR* pChecksum) {
  CFDE_XMLDoc* pXMLDoc = m_pDocument->GetParser()->GetXMLDoc();
  if (pNode->GetObjectType() == XFA_OBJECTTYPE_ModelNode) {
    switch (pNode->GetPacketID()) {
      case XFA_XDPPACKET_XDP: {
        static const FX_WCHAR s_pwsPreamble[] =
            L"<xdp:xdp xmlns:xdp=\"http://ns.adobe.com/xdp/\">";
        pStream->WriteString(s_pwsPreamble, FXSYS_wcslen(s_pwsPreamble));
        for (CXFA_Node* pChild = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
             pChild; pChild = pChild->GetNodeItem(XFA_NODEITEM_NextSibling)) {
          Export(pStream, pChild, dwFlag, pChecksum);
        }
        static const FX_WCHAR s_pwsPostamble[] = L"</xdp:xdp\n>";
        pStream->WriteString(s_pwsPostamble, FXSYS_wcslen(s_pwsPostamble));
      } break;
      case XFA_XDPPACKET_Datasets: {
        CFDE_XMLElement* pElement =
            static_cast<CFDE_XMLElement*>(pNode->GetXMLMappingNode());
        if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
          return FALSE;
        }
        CXFA_Node* pDataNode = pNode->GetNodeItem(XFA_NODEITEM_FirstChild);
        ASSERT(pDataNode);
        XFA_DataExporter_DealWithDataGroupNode(pDataNode);
        pXMLDoc->SaveXMLNode(pStream, pElement);
      } break;
      case XFA_XDPPACKET_Form: {
        XFA_DataExporter_RegenerateFormFile(pNode, pStream, pChecksum);
      } break;
      case XFA_XDPPACKET_Template:
      default: {
        CFDE_XMLElement* pElement =
            static_cast<CFDE_XMLElement*>(pNode->GetXMLMappingNode());
        if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
          return FALSE;
        }
        pXMLDoc->SaveXMLNode(pStream, pElement);
      } break;
    }
  } else {
    CXFA_Node* pDataNode = pNode->GetNodeItem(XFA_NODEITEM_Parent);
    CXFA_Node* pExportNode = pNode;
    for (CXFA_Node* pChildNode =
             pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild);
         pChildNode;
         pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
      if (pChildNode != pNode) {
        pExportNode = pDataNode;
        break;
      }
    }
    CFDE_XMLElement* pElement =
        static_cast<CFDE_XMLElement*>(pExportNode->GetXMLMappingNode());
    if (!pElement || pElement->GetType() != FDE_XMLNODE_Element) {
      return FALSE;
    }
    XFA_DataExporter_DealWithDataGroupNode(pExportNode);
    pElement->SetString(L"xmlns:xfa",
                        L"http://www.xfa.org/schema/xfa-data/1.0/");
    pXMLDoc->SaveXMLNode(pStream, pElement);
    pElement->RemoveAttribute(L"xmlns:xfa");
  }
  return TRUE;
}
void XFA_DataExporter_DealWithDataGroupNode(CXFA_Node* pDataNode) {
  if (!pDataNode || pDataNode->GetClassID() == XFA_ELEMENT_DataValue) {
    return;
  }
  int32_t iChildNum = 0;
  for (CXFA_Node* pChildNode = pDataNode->GetNodeItem(XFA_NODEITEM_FirstChild);
       pChildNode;
       pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling)) {
    iChildNum++;
    XFA_DataExporter_DealWithDataGroupNode(pChildNode);
  }
  if (pDataNode->GetClassID() == XFA_ELEMENT_DataGroup) {
    if (iChildNum > 0) {
      CFDE_XMLNode* pXMLNode = pDataNode->GetXMLMappingNode();
      ASSERT(pXMLNode->GetType() == FDE_XMLNODE_Element);
      CFDE_XMLElement* pXMLElement = static_cast<CFDE_XMLElement*>(pXMLNode);
      if (pXMLElement->HasAttribute(L"xfa:dataNode")) {
        pXMLElement->RemoveAttribute(L"xfa:dataNode");
      }
    } else {
      CFDE_XMLNode* pXMLNode = pDataNode->GetXMLMappingNode();
      ASSERT(pXMLNode->GetType() == FDE_XMLNODE_Element);
      static_cast<CFDE_XMLElement*>(pXMLNode)->SetString(L"xfa:dataNode",
                                                         L"dataGroup");
    }
  }
}
