如何获取Xml命名空间解析器

时间:2013-02-05 16:54:40

标签: c# xml xml-namespaces

我正在尝试调用需要IXmlNamespaceResolver对象的XElement.XPathSelectElements()重载。谁能告诉我如何获取(或制作)IXmlNamespaceResolver?我有一个我想在查询中使用的命名空间列表

3 个答案:

答案 0 :(得分:11)

使用lodash.defaults(lessdata, moredata);

例如,如果您有一个使用

等命名空间的XML文档
new XmlNamespaceManager(new NameTable())

然后您可以通过

获取var xDoc = XDocument.Parse(@"<m:Student xmlns:m='http://www.ludlowcloud.com/Math'> <m:Grade>98</m:Grade> <m:Grade>96</m:Grade> </m:Student>"); 个节点
Grade

答案 1 :(得分:7)

您可以使用实现该接口的XmlNamespaceManager

使用带有XmlNameTable的构造函数,通过new NameTable()向其传递System.Xml.NameTable的实例。然后,您可以调用AddNamespace函数来添加名称空间:

var nsMgr = new XmlNamespaceManager(new NameTable());
nsMgr.AddNamespace("ex", "urn:example.org");
nsMgr.AddNamespace("t", "urn:test.org");
doc.XPathSelectElements("/ex:path/ex:to/t:element", nsMgr);

答案 2 :(得分:4)

我在搜索如何使用[XPathSelectElements()]的重载来处理SOAP响应时发现了这篇文章,所以,我将发布我的答案,以防它对于拥有多个命名空间定义的文档的其他人有用。就我而言,我有一个这样的文件:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <queryResponse xmlns="http://SomeUrl.com/SomeSection">
      <response>
        <theOperationId>105</theOperationId>
        <theGeneraltheDetailsCode>0</theGeneraltheDetailsCode>
        <theDetails>
          <aDetail>
            <aDetailId>111</aDetailId>
            <theValue>Some Value</theValue>
            <theDescription>Some description</theDescription>
          </aDetail>
          <aDetail>
            <aDetailId>222</aDetailId>
            <theValue>Another Value</theValue>
            <theDescription>Another description</theDescription>
          </aDetail>
          <aDetail>
            <aDetailId>333</aDetailId>
            <theValue>And another Value</theValue>
            <theDescription>And another description</theDescription>
          </aDetail>
        </theDetails>
      </response>
    </queryResponse>
  </soap:Body>
</soap:Envelope>

创建[XDocument]:

var theDocumentXDoc = XDocument.Parse( theDocumentContent );

要创建[XmlNamespaceManager],我使用:

var theNamespaceIndicator = new XmlNamespaceManager( new NameTable() );
theNamespaceIndicator.AddNamespace( "theSoapNS", "http://www.w3.org/2003/05/soap-envelope" );
theNamespaceIndicator.AddNamespace( "noSuffNS" , "http://SomeUrl.com/SomeSection" );

我用于前缀的名称(&#34; theSoapNS&#34;和&#34; noSuffNS&#34;)是任意的。使用便于可读代码的名称。

要选择[Envelope]元素,我使用:

var theEnvelope = theDocumentXDoc.XPathSelectElement( "//theSoapNS:Envelope", theNamespaceIndicator );

选择[queryResponse]元素:

var theQueryResponse = theDocumentXDoc.XPathSelectElement( "//theSoapNS:Envelope/theSoapNS:Body/noSuffNS:queryResponse", theNamespaceIndicator );

选择[详细信息]中的所有详细信息:

var theDetails = theDocumentXDoc.XPathSelectElement( "//theSoapNS:Envelope/theSoapNS:Body/noSuffNS:queryResponse/noSuffNS:response/noSuffNS:theDetails", theNamespaceIndicator );

以下是使用选择的示例程序(C#6):

//The usings you need:
using System;
using System.Linq;
using System.Xml;
using System.Xml.Linq;
using System.Xml.XPath;

namespace ProcessXmlCons
{
    class Inicial
    {
        static void Main(string[] args)
        {
            new Inicial().Tests();
        }

        private void Tests()
        {
            Test01();
        }

        private void Test01()
        {
            var theDocumentContent =
              @"<?xml version=""1.0"" encoding=""utf-8""?>
                    <soap:Envelope xmlns:soap=""http://www.w3.org/2003/05/soap-envelope"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
                        <soap:Body>
                        <queryResponse xmlns=""http://SomeUrl.com/SomeSection"">
                            <response>
                                <theOperationId>105</theOperationId>
                                <theGeneraltheDetailsCode>0</theGeneraltheDetailsCode>
                                <theDetails>
                                    <aDetail>
                                        <aDetailId>111</aDetailId>
                                        <theValue>Some Value</theValue>
                                        <theDescription>Some description</theDescription>
                                    </aDetail>
                                    <aDetail>
                                        <aDetailId>222</aDetailId>
                                        <theValue>Another Value</theValue>
                                        <theDescription>Another description</theDescription>
                                    </aDetail>
                                    <aDetail>
                                        <aDetailId>333</aDetailId>
                                        <theValue>And another Value</theValue>
                                        <theDescription>And another description</theDescription>
                                    </aDetail>
                                </theDetails>
                            </response>
                        </queryResponse>
                        </soap:Body>
                    </soap:Envelope>
                    ";

            var theDocumentXDoc = XDocument.Parse(theDocumentContent);
            var theNamespaceIndicator = new XmlNamespaceManager(new NameTable());
            theNamespaceIndicator.AddNamespace("theSoapNS", "http://www.w3.org/2003/05/soap-envelope");
            theNamespaceIndicator.AddNamespace("noSuffNS", "http://SomeUrl.com/SomeSection");

            var theEnvelope = theDocumentXDoc.XPathSelectElement("//theSoapNS:Envelope", theNamespaceIndicator);
            Console.WriteLine($"The envelope: {theEnvelope?.ToString()} ");

            var theEnvelopeNotFound = theDocumentXDoc.XPathSelectElement("//Envelope", theNamespaceIndicator);
            Console.WriteLine("".PadRight(120, '_')); //Visual divider
            Console.WriteLine($"The other envelope: \r\n {theEnvelopeNotFound?.ToString()} ");

            var theQueryResponse = theDocumentXDoc.XPathSelectElement("//theSoapNS:Envelope/theSoapNS:Body/noSuffNS:queryResponse", theNamespaceIndicator);
            Console.WriteLine("".PadRight(120, '_')); //Visual divider
            Console.WriteLine($"The query response: \r\n {theQueryResponse?.ToString()} ");

            var theDetails = theDocumentXDoc.XPathSelectElement("//theSoapNS:Envelope/theSoapNS:Body/noSuffNS:queryResponse/noSuffNS:response/noSuffNS:theDetails", theNamespaceIndicator);
            Console.WriteLine("".PadRight(120, '_')); //Visual divider
            Console.WriteLine($"The details: \r\n {theDetails?.ToString()} ");
            Console.WriteLine("".PadRight(120, '_')); //Visual divider

            foreach (var currentDetail in theDetails.Descendants().Where(elementToFilter => elementToFilter.Name.LocalName != "aDetail"))
            {
                Console.WriteLine($"{currentDetail.Name.LocalName}: {currentDetail.Value}");
            }

            //Not optimal. Just to show XPath select within another selection:
            Console.WriteLine("".PadRight(120, '_')); //Visual divider
            Console.WriteLine("Values only:");
            foreach (var currentDetail in theDetails.Descendants())
            {
                var onlyTheValueElement = currentDetail.XPathSelectElement("noSuffNS:theValue", theNamespaceIndicator);
                if (onlyTheValueElement != null)
                {
                    Console.WriteLine($"--> {onlyTheValueElement.Value}");
                }
            }
        }

    } //class Inicial
} //namespace ProcessXmlCons