C# 使用信封重载xml中的名称空间

C# 使用信封重载xml中的名称空间,c#,xml,namespaces,envelope,C#,Xml,Namespaces,Envelope,我有一个程序,可以遍历XML文档来搜索值。 我想提取我找到的文档的版本号,并将其添加到搜索结果中 我遇到的问题是,文档有很多不同的名称空间,而且大多数都有一个信封。信封具有与文档有效负载中的不同名称空间相同的名称空间前缀。 我正在努力从有效负载中提取值,因为我无法获取内部文档的名称空间 if (myX != null) { XNamespace myNs; if (myX.Root.FirstAttribute == null) myNs = ""; el

我有一个程序,可以遍历XML文档来搜索值。 我想提取我找到的文档的版本号,并将其添加到搜索结果中

我遇到的问题是,文档有很多不同的名称空间,而且大多数都有一个信封。信封具有与文档有效负载中的不同名称空间相同的名称空间前缀。 我正在努力从有效负载中提取值,因为我无法获取内部文档的名称空间

if (myX != null)
{
    XNamespace myNs;
    if (myX.Root.FirstAttribute == null)
        myNs = "";
    else
    {
        myNs = myX.Root.FirstAttribute.Value;
        var dummy2 = myX.Root.Descendants("Message").First().FirstAttribute;
        var dummy1 = myX.Root.Descendants(myNs + "Message").First().FirstAttribute;

    }


    foreach (XNode xN in myX.Root.DescendantNodes())
    {
        if (xN is XElement)
        {
            if (!wildcard)
            {
                if (((XElement)xN).Value == value)
                {
                    myResultSet[0].Add(new ResultSet(file, myX.Root.Descendants(myNs + "MessageVersion").First().Value));
                }
            }
            else if (wildcard)
            {
                if (((XElement)xN).Value.Contains(value))
                {
                    myResultSet[0].Add(new ResultSet(file, myX.Root.Descendants(myNs + "MessageVersion").First().Value));
                }
            }
        }
    }
}
我可以获得ns0:Body元素,但无法获得任何与名称空间相关的内容。 XML是这样的:

<ns0:Envelope xmlns:ns0="http://dummy.schema.com/ss2/schemas/2.3">
  <ns0:SenderILN>123456789123</ns0:SenderILN>
  <ns0:ReceiverILN>987654321987</ns0:ReceiverILN>
  <ns0:EnvelopeNumber>12345</ns0:EnvelopeNumber>
  <ns0:Body>
    <ns0:Message xmlns:ns0="http://dummy.schema.com/ss2/schemas/2.5/DESADV">
      <ns0:Header>
        <ns0:MessageType>DESADV</ns0:MessageType>
        <ns0:SenderILN>123456789123</ns0:SenderILN>1
        <ns0:ReceiverILN>987654321987</ns0:ReceiverILN>
        <ns0:MessageVersion>2.5</ns0:MessageVersion>
      </ns0:Header>
      <ns0:DESADV>
        <ns0:Payload />
      </ns0:DESADV>
    </ns0:Message>
  </ns0:Body>
</ns0:Envelope>
XNamespace ns = "http://dummy.schema.com/ss2/schemas/2.5/DESADV"

var version = (string) doc
    .Descendants(ns + "MessageVersion")
    .Single();
是否有可能在不首先移除信封的情况下获取内部消息

if (((XElement)xN).Value == value)
{
    XNamespace myNs = ((XElement)xN).Name.Namespace;
    myResultSet[0].Add(new ResultSet(file, myX.Root.Descendants(myNs + "MessageVersion").First().Value));
}
在从结果而不是文档本身开始之后,提取名称空间和值非常容易


但这只起作用,因为我是蛮力地强迫文档的。我找不到冷静的解决办法。。。仍在寻找更好的解决方案。

我不确定您为什么要尝试“提取”名称空间。名称空间是元素名称的一部分-正如您知道本地名称MessageVersion一样,您也应该知道其名称空间

你应该这样做:

<ns0:Envelope xmlns:ns0="http://dummy.schema.com/ss2/schemas/2.3">
  <ns0:SenderILN>123456789123</ns0:SenderILN>
  <ns0:ReceiverILN>987654321987</ns0:ReceiverILN>
  <ns0:EnvelopeNumber>12345</ns0:EnvelopeNumber>
  <ns0:Body>
    <ns0:Message xmlns:ns0="http://dummy.schema.com/ss2/schemas/2.5/DESADV">
      <ns0:Header>
        <ns0:MessageType>DESADV</ns0:MessageType>
        <ns0:SenderILN>123456789123</ns0:SenderILN>1
        <ns0:ReceiverILN>987654321987</ns0:ReceiverILN>
        <ns0:MessageVersion>2.5</ns0:MessageVersion>
      </ns0:Header>
      <ns0:DESADV>
        <ns0:Payload />
      </ns0:DESADV>
    </ns0:Message>
  </ns0:Body>
</ns0:Envelope>
XNamespace ns = "http://dummy.schema.com/ss2/schemas/2.5/DESADV"

var version = (string) doc
    .Descendants(ns + "MessageVersion")
    .Single();
如果出于某种原因您不知道或不关心名称空间,您可以按本地名称搜索:

var version = (string) doc
    .Descendants()
    .Single(x => x.Name.LocalName == "MessageVersion");

第一种解决方案并不合适,因为有十几个不同的文档具有不同的名称空间-手动更新名称空间列表将是一件痛苦的事情。第二个解决方案返回一个异常:序列在同一个文件中不包含任何数据。我的扩展代码与下面的答案返回的值相同。如果我在代码中没有使用正确的名称空间,我也会遇到这个异常,这就是为什么我对名称空间如此着迷的原因@我想这是合理的。但是,我有点惊讶,所有这些具有不同名称空间的文档都具有相同的MessageVersion元素。我不确定您是否犯了错误-您可以从中看出代码与您的示例是一致的。注意,我注意到这个示例没有编译,但我认为您已经解决了这个问题。我已经更新了密码……这确实可疑。我会用原始文件测试它,如果我知道的更多,我会写回去。它不起作用的原因是我太笨了。你的代码运行正常,我又觉得不可思议的愚蠢了:-\。谢谢你的帮助。MessageVersion始终存在的问题是,我的每条消息都有一个相同的头部分。