【问题标题】:XmlDocument.SelectNodes returns no nodes for InfoPath XMLXmlDocument.SelectNodes 不返回 InfoPath XML 的节点
【发布时间】:2015-07-27 14:27:39
【问题描述】:

我正在尝试查询 InfoPath XML 文档中的附件,但查询未能返回任何节点。我没有太多使用 XmlDocument 类的经验。我相信我的问题与命名空间有关。有没有人对此有任何见解。

代码

// Get the binary stream of the file
Stream formStream = file.OpenBinaryStream();
// Load the stream into an XPathDocument object
XmlDocument ipForm = new XmlDocument();
ipForm.Load(formStream);

//Create a NameSpaceManager object and add the namespace of the form to it
XmlNamespaceManager ns = new XmlNamespaceManager(ipForm.NameTable);
ns.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2015-07-13T20:54:32"); //http://schemas.microsoft.com/office/infopath/2003/myXSD/2015-07-13T20:54:32 | http://www.w3.org/XML/1998/namespace

  //Get the XML node containing the file attachment
  //XmlNode attachmentNode = ipForm.SelectSingleNode("/my:myFields/my:Attachments", ns);

 //No nodes returned here 
 XmlNodeList myNodeList = ipForm.SelectNodes("/my:myFields/my:Attachments", ns); 

XML

<?xml version="1.0" encoding="UTF-8"?><?mso-infoPathSolution solutionVersion="1.0.0.830" productVersion="14.0.0" PIVersion="1.0.0.0" href="http://sharepoint.calpine.com/sites/dept/fleetsupport/issues/Issues/Forms/template.xsn" name="urn:schemas-microsoft-com:office:infopath:Issues:-myXSD-2015-03-30T21-16-50" ?><?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.3"?><?mso-infoPath-file-attachment-present?><my:myFields xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pc="http://schemas.microsoft.com/office/infopath/2007/PartnerControls" xmlns:ma="http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes" xmlns:d="http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields" xmlns:q="http://schemas.microsoft.com/office/infopath/2009/WSSList/queryFields" xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution" xmlns:dms="http://schemas.microsoft.com/office/2009/documentManagement/types" xmlns:tns="http://schemas.microsoft.com/sharepoint/soap/" xmlns:s1="http://microsoft.com/wsdl/types/" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:ns1="http://microsoft.com/webservices/SharePointPortalServer/UserProfileService" xmlns:ns2="http://schemas.microsoft.com/sharepoint/soap/directory/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:ns3="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2015-03-30T21:16:50" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" xml:lang="en-us">
<my:InstrumentTag>222</my:InstrumentTag>
<my:IssueDate>2015-07-25</my:IssueDate> 
<my:listName>{B6CDAA90-0F94-4127-A50F-D599952B23CD}</my:listName>
<my:strFormName>TestFormName</my:strFormName>   
<my:Attachments>
    <my:Attachment>/*AttachmentBinary*/</my:Attachment>
</my:Attachments>
<my:Attachments>
    <my:Attachment>/*AttachmentBinary*/</my:Attachment>
</my:Attachments>

【问题讨论】:

  • 您的代码和 XML 使用两个不同的命名空间 - 2015-03-30T21:16:50 != 2015-07-13T20:54:32
  • 我应该使用 2015-03-30T21:16:50 吗?
  • 使用该命名空间有效。我如何知道要使用哪个命名空间?
  • 我怀疑 InfoPath 在生成时向 XMLNS 添加了日期时间。使用XmlReader 或使用XDocument 查找本地名称而不是使用命名空间前缀可能会做得更好。
  • @Damien_The_Unbeliever 您的评论就是答案。如果您创建一个,我将标记为已解决。

标签: c# xml xpath xmldocument infopath2010


【解决方案1】:

试试这个

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication37
{
    class Program
    {
        const string FILENAME = @"\temp\test.xml";
        static void Main(string[] args)
        {

            XDocument doc = XDocument.Load(FILENAME);

            var results = doc.Descendants().Where(x => x.Name.LocalName == "myFields").Select(y => new
            {
                instrumentTag = y.Elements().Where(z => z.Name.LocalName == "InstrumentTag").FirstOrDefault().Value,
                issueDate = y.Elements().Where(z => z.Name.LocalName == "IssueDate").FirstOrDefault().Value,
                listName = y.Elements().Where(z => z.Name.LocalName == "listName").FirstOrDefault().Value,
                strFormName = y.Elements().Where(z => z.Name.LocalName == "strFormName").FirstOrDefault().Value,
                Attachments = y.Elements().Where(z => z.Name.LocalName == "Attachments").Select(a => new {
                   attachment = a.Elements().Where(b => b.Name.LocalName == "Attachment").Select(c => c.Value).FirstOrDefault()
                }).ToList(),
            }).ToList();
        }
    }
}

【讨论】:

  • 是的,这可能更好,只要XDocument 是他的选项。
【解决方案2】:

如果您确定命名空间在您的情况下没有任何意义,您可以通过在 XPath 中使用 local-name() 来忽略它们,例如:

var xpathQuery = "/*[local-name()='myFields']/*[local-name()='Attachments']";
XmlNodeList myNodeList = ipForm.SelectNodes(xpathQuery); 

【讨论】:

    【解决方案3】:

    您的 XML 看起来很奇怪。

    为什么 Attachements 不包含这两个节点?!

    而且,即使我不太了解 InfoPath,您要查找的“myFields”节点是什么,它似乎也不存在于您的 XML 示例中。

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      • 2016-02-23
      • 2017-08-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多