迭代和infoPath表单

时间:2012-10-03 12:17:26

标签: c# sharepoint-2007 infopath

我有一个可能包含多个附件的信息表格:通过使用一组重复元素,用户可以点击“点击添加项目”选项,他将能够上传更多附件。 在Sharepoint中,我使用工作流来提取附件并将​​它们放在单独的列表中。到目前为止,我只管理提取第一个,工作流程成功完成。

我可以放一个循环或者某些东西来迭代表格吗?

我附上以下代码:

    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; }
        }

1 个答案:

答案 0 :(得分:0)

您的问题似乎与您使用MoveToNext有关。 Per the documentation,此函数移动到下一个兄弟,并且不会导航到子元素。您的代码似乎转到它找到的第一个元素(可能是my:myFields),查找名为my:field2的第一个子项(它仅在您使用SelectSingleNode时拉出第一个子项,然后转到my:myFields的下一个兄弟(不是my:field2的下一个兄弟)。修复此问题的一种方法可能是通过调用SelectNodes替换当前的do-while循环如下所示,然后迭代nodeList

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