2012-10-03 3 views
2

여러 첨부 파일을 포함 할 수있는 정보가있는 양식 : 반복되는 요소 그룹을 사용하여 사용자가 "첨부 항목 추가"옵션을 클릭하면 더 많은 첨부 파일을 업로드 할 수 있습니다. Sharepoint에서 첨부 파일을 추출하고 별도의 목록에 넣으려는 워크 플로를 사용하고 있습니다. 지금까지는 첫 번째 파일 만 추출하고 워크 플로가 성공적으로 완료되었습니다.통해 반복하고 infoPath 양식

루프 또는 무언가를 물결 모양으로 반복 할 수 있습니까?

public sealed partial class FileCopyFeature : SharePointSequentialWorkflowActivity 
    { 
     public FileCopyFeature() 
     { 
      InitializeComponent(); 
     } 

     public Guid workflowId = default(System.Guid); 
     public Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties workflowProperties = new Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties(); 

     private void CopyFile(object sender, EventArgs e) 
     { 

      // Retrieve the file associated with the item 
      // on which the workflow has been instantiated 
      SPFile file = workflowProperties.Item.File; 

      if (file == null) 
       return; 

      // Get the binary data of the file 
      byte[] xmlFormData = null; 
      xmlFormData = file.OpenBinary(); 

      // Load the data into an XPathDocument object 
      XPathDocument ipForm = null; 

      if (xmlFormData != null) 
      { 
       using (MemoryStream ms = new MemoryStream(xmlFormData)) 
       { 
        ipForm = new XPathDocument(ms); 
        ms.Close(); 
       } 
      } 

      if (ipForm == null) 
       return; 

      // Create an XPathNavigator object to navigate the XML 
      XPathNavigator ipFormNav = ipForm.CreateNavigator(); 

      ipFormNav.MoveToFollowing(XPathNodeType.Element); 
      XmlNamespaceManager nsManager = 
      new XmlNamespaceManager(new NameTable()); 

      foreach (KeyValuePair<string, string> ns 
      in ipFormNav.GetNamespacesInScope(XmlNamespaceScope.All)) 
      { 
       if (ns.Key == String.Empty) 
       { 
        nsManager.AddNamespace("def", ns.Value); 
       } 
       else 
       { 
        nsManager.AddNamespace(ns.Key, ns.Value); 
       } 
      } 

      do 
      { 


       XPathNavigator nodeNav = ipFormNav.SelectSingleNode("//my:field2", nsManager); 


       // Retrieve the value of the attachment in the InfoPath form 
       //XPathNavigator nodeNav = ipFormNav.SelectSingleNode(
       //"//my:field2", nsManager); 

       string ipFieldValue = string.Empty; 
       if (nodeNav != null) 
       { 
        ipFieldValue = nodeNav.Value; 

        // Decode the InfoPath file attachment 
        InfoPathAttachmentDecoder dec = 
        new InfoPathAttachmentDecoder(ipFieldValue); 
        string fileName = dec.Filename; 
        byte[] data = dec.DecodedAttachment; 

        // Add the file to a document library 
        using (SPWeb web = workflowProperties.Web) 
        { 
         SPFolder docLib = web.Folders["Doc"]; 
         docLib.Files.Add(fileName, data); 
         docLib.Update(); 
         // workflowProperties.Item.CopyTo(data + "/Doc/" + fileName); 
        } 

       } 

      } 
      while (ipFormNav.MoveToNext()); 

     } 
    } 
    /// <summary> 
    /// Decodes a file attachment and saves it to a specified path. 
    /// </summary> 
    public class InfoPathAttachmentDecoder 
    { 
     private const int SP1Header_Size = 20; 
     private const int FIXED_HEADER = 16; 

     private int fileSize; 
     private int attachmentNameLength; 
     private string attachmentName; 
     private byte[] decodedAttachment; 

     /// <summary> 
     /// Accepts the Base64 encoded string 
     /// that is the attachment. 
     /// </summary> 
     public InfoPathAttachmentDecoder(string theBase64EncodedString) 
     { 
      byte[] theData = Convert.FromBase64String(theBase64EncodedString); 
      using (MemoryStream ms = new MemoryStream(theData)) 
      { 
       BinaryReader theReader = new BinaryReader(ms); 
       DecodeAttachment(theReader); 
      } 
     } 

     private void DecodeAttachment(BinaryReader theReader) 
     { 
      //Position the reader to get the file size. 
      byte[] headerData = new byte[FIXED_HEADER]; 
      headerData = theReader.ReadBytes(headerData.Length); 

      fileSize = (int)theReader.ReadUInt32(); 
      attachmentNameLength = (int)theReader.ReadUInt32() * 2; 

      byte[] fileNameBytes = theReader.ReadBytes(attachmentNameLength); 
      //InfoPath uses UTF8 encoding. 
      Encoding enc = Encoding.Unicode; 
      attachmentName = enc.GetString(fileNameBytes, 0, attachmentNameLength - 2); 
      decodedAttachment = theReader.ReadBytes(fileSize); 
     } 

     public void SaveAttachment(string saveLocation) 
     { 
      string fullFileName = saveLocation; 
      if (!fullFileName.EndsWith(Path.DirectorySeparatorChar.ToString())) 
      { 
       fullFileName += Path.DirectorySeparatorChar; 
      } 

      fullFileName += attachmentName; 

      if (File.Exists(fullFileName)) 
       File.Delete(fullFileName); 

      FileStream fs = new FileStream(fullFileName, FileMode.CreateNew); 
      BinaryWriter bw = new BinaryWriter(fs); 
      bw.Write(decodedAttachment); 

      bw.Close(); 
      fs.Close(); 
     } 

     public string Filename 
     { 
      get { return attachmentName; } 
     } 

     public byte[] DecodedAttachment 
     { 
      get { return decodedAttachment; } 
     } 

답변

0

당신의 문제가 MoveToNext의 사용과 관련이 나타납니다 :

나는 아래의 코드를 연결합니다. Per the documentation이 함수는 다음 형제로 이동하고 children 요소로 이동하지 않습니다. 코드는 발견 된 첫 번째 요소 (아마도 my:myFields)로 이동하고 my:field2이라는 첫 번째 자식을 찾습니다 (SelectSingleNode을 사용하고 있기 때문에 첫 번째 코드 만 가져오고 다음 형제 인 my:myFields (다음 형제가 아님)로 이동합니다 my:field2). 한 가지 방법이 다음과 같은 SelectNodes를 호출하여 현재 do-while 루프를 교체 한 후 nodeList을 반복 할 수 있습니다 수정합니다.

XmlNodeList nodelist = ipFormNav.SelectNodes("//my:field2", nsManager); 
관련 문제