搜索使用LINQ的XDocument不知道该命名空间 [英] Search XDocument using LINQ without knowing the namespace

查看:227
本文介绍了搜索使用LINQ的XDocument不知道该命名空间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法来搜索一个XDocument不知道该命名空间?我有记录所有的SOAP请求和加密敏感数据的过程。我想找到基于名称的任何元素。喜欢的东西,给我的所有元素,其中名称是信用卡式。我不在乎名称空间是什么。

我的问题似乎与LINQ和需要XML命名空间。

我有一个从XML检索值等工序,但我知道这些其他过程的命名空间。

 的XDocument的XDocument = XDocument.Load(@C:\\ TEMP \\ Packet.xml);
的XNamespace的XNamespace =HTTP://CompanyName.AppName.Service.ContractsVAR元素= xDocument.Root
                        .DescendantsAndSelf()
                        .Elements()
                        。凡(D => d.Name ==的XNamespace +CreditCardNumber);

我真的想搜索的XML不知道关于命名空间的能力,是这样的:

 的XDocument的XDocument = XDocument.Load(@C:\\ TEMP \\ Packet.xml);
VAR元素= xDocument.Root
                        .DescendantsAndSelf()
                        .Elements()
                        。凡(D => d.Name ==CreditCardNumber)

这是行不通的,因为我没有在编译时知道该命名空间事先。

如何才能做到这一点?

 < S:信封的xmlns:S =htt​​p://schemas.xmlsoap.org/soap/envelope/>
< S:身体的xmlns:XSI =htt​​p://www.w3.org/2001/XMLSchema-instance的xmlns:XSD =htt​​p://www.w3.org/2001/XMLSchema>
    <请求的xmlns =HTTP://CompanyName.AppName.Service.ContractA>
        <&人GT;
            < CreditCardNumber> 83838< / CreditCardNumber>
            <&名字GT;汤姆和LT; /姓>
            <&姓氏GT;&杰克逊LT; /姓氏>
        < /人>
        <&人GT;
            < CreditCardNumber> 789875< / CreditCardNumber>
            <&名字GT;克里斯< /姓>
            <&姓氏GT;史密斯和LT; /姓氏>
        < /人>
        ...< S:信封的xmlns:S =htt​​p://schemas.xmlsoap.org/soap/envelope/>
< S:身体的xmlns:XSI =htt​​p://www.w3.org/2001/XMLSchema-instance的xmlns:XSD =htt​​p://www.w3.org/2001/XMLSchema>
    <请求的xmlns =HTTP://CompanyName.AppName.Service.ContractsB>
        <&交易GT;
            < CreditCardNumber> 83838< / CreditCardNumber>
            <&的TransactionID GT; 64588< /姓>
        < /交易>
        ...


解决方案

由于在评论亚当precises,XName的是转换为一个字符串,但该字符串需要空间的时候有一个。这就是为什么.Name点的一个字符串比较失败,或者你为什么不能传递人作为参数传递给XLINQ方法上他们的名字进行筛选。结果
的XName由preFIX(命名空间),且localName的。本地名称是您要查询的,如果你忽略了命名空间的东西。结果
谢谢亚当:)

您不能把名称节点作为.Descendants()方法的参数,但可以查询这种方式:

  VAR DOC = XElement.Parse(
@< S:信封的xmlns:S =http://schemas.xmlsoap.org/soap/envelope/>
< S:身体的xmlns:XSI =http://www.w3.org/2001/XMLSchema-instance的xmlns:XSD =http://www.w3.org/2001/XMLSchema&GT ;
  <请求的xmlns =的http://CompanyName.AppName.Service.ContractA>
    <&人GT;
        < CreditCardNumber> 83838< / CreditCardNumber>
        <&名字GT;汤姆和LT; /姓>
        <&姓氏GT;&杰克逊LT; /姓氏>
    < /人>
    <&人GT;
        < CreditCardNumber> 789875< / CreditCardNumber>
        <&名字GT;克里斯< /姓>
        <&姓氏GT;史密斯和LT; /姓氏>
    < /人>
   < /请求>
   < / S:身体与GT;
< / S:信封>);

编辑: 坏的复制/过去从我的测试:)

 变种人=从doc.Descendants P()
              其中,p.Name.LocalName ==人
              器选择p;的foreach(在人VAR P)
{
    Console.WriteLine(P);
}

这为我的作品...

Is there a way to search an XDocument without knowing the namespace? I have a process that logs all SOAP requests and encrypts the sensitive data. I want to find any elements based on name. Something like, give me all elements where the name is CreditCard. I don't care what the namespace is.

My problem seems to be with LINQ and requiring a xml namespace.

I have other processes that retrieve values from XML, but I know the namespace for these other process.

XDocument xDocument = XDocument.Load(@"C:\temp\Packet.xml");
XNamespace xNamespace = "http://CompanyName.AppName.Service.Contracts";

var elements = xDocument.Root
                        .DescendantsAndSelf()
                        .Elements()
                        .Where(d => d.Name == xNamespace + "CreditCardNumber");

I really want to have the ability to search xml without knowing about namespaces, something like this:

XDocument xDocument = XDocument.Load(@"C:\temp\Packet.xml");
var elements = xDocument.Root
                        .DescendantsAndSelf()
                        .Elements()
                        .Where(d => d.Name == "CreditCardNumber")

This will not work because I don't know the namespace beforehand at compile time.

How can this be done?

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Request xmlns="http://CompanyName.AppName.Service.ContractA">
        <Person>
            <CreditCardNumber>83838</CreditCardNumber>
            <FirstName>Tom</FirstName>
            <LastName>Jackson</LastName>
        </Person>
        <Person>
            <CreditCardNumber>789875</CreditCardNumber>
            <FirstName>Chris</FirstName>
            <LastName>Smith</LastName>
        </Person>
        ...

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Request xmlns="http://CompanyName.AppName.Service.ContractsB">
        <Transaction>
            <CreditCardNumber>83838</CreditCardNumber>
            <TransactionID>64588</FirstName>
        </Transaction>      
        ...

解决方案

As Adam precises in the comment, XName are convertible to a string, but that string requires the namespace when there is one. That's why the comparison of .Name to a string fails, or why you can't pass "Person" as a parameter to the XLinq Method to filter on their name.
XName consists of a prefix (the Namespace) and a LocalName. The local name is what you want to query on if you are ignoring namespaces.
Thank you Adam :)

You can't put the Name of the node as a parameter of the .Descendants() method, but you can query that way :

var doc= XElement.Parse(
@"<s:Envelope xmlns:s=""http://schemas.xmlsoap.org/soap/envelope/"">
<s:Body xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
  <Request xmlns=""http://CompanyName.AppName.Service.ContractA"">
    <Person>
        <CreditCardNumber>83838</CreditCardNumber>
        <FirstName>Tom</FirstName>
        <LastName>Jackson</LastName>
    </Person>
    <Person>
        <CreditCardNumber>789875</CreditCardNumber>
        <FirstName>Chris</FirstName>
        <LastName>Smith</LastName>
    </Person>
   </Request>
   </s:Body>
</s:Envelope>");

EDIT : bad copy/past from my test :)

var persons = from p in doc.Descendants()
              where p.Name.LocalName == "Person"
              select p;

foreach (var p in persons)
{
    Console.WriteLine(p);
}

That works for me...

这篇关于搜索使用LINQ的XDocument不知道该命名空间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆