Ищите XDocument, использующий LINQ, не зная пространство имен

Существует ли способ искать XDocument, не зная пространство имен? У меня есть процесс, который регистрирует все запросы SOAP и шифрует уязвимые данные. Я хочу найти любые элементы на основе имени. Что-то как, дайте мне все элементы, где именем является CreditCard. Я не забочусь, каково пространство имен.

Моя проблема, кажется, с LINQ и требованием xml пространства имен.

У меня есть другие процессы, которые получают значения от XML, но я знаю пространство имен для них другой процесс.

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");

Я действительно хочу иметь способность искать xml, не зная о пространствах имен, чем-то вроде этого:

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

Это не будет работать, потому что я не знаю пространство имен заранее во время компиляции.

Как это может быть сделано?

<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>      
        ...
73
задан p.campbell 13 October 2012 в 02:38
поделиться

3 ответа

Как уточнил Адам в комментарии, XName преобразуются в строку, но эта строка требует пространства имен, если оно есть. Вот почему сравнение .Name со строкой не удается, или почему вы не можете передать "Person" в качестве параметра методу XLinq для фильтрации по имени.
XName состоит из префикса (пространство имен) и LocalName. Локальное имя - это то, что вы хотите запрашивать, если вы игнорируете пространства имен.
Спасибо, Адам :)

Вы не можете поместить имя узла в качестве параметра метода .Descendants(), но вы можете запрашивать таким образом :

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 : плохой copy/past из моего теста :)

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

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

Это работает для меня...

85
ответ дан 24 November 2019 в 12:13
поделиться

Просто используйте метод потомков:

XDocument doc = XDocument.Load(filename);
String[] creditCards = (from creditCardNode in doc.Root.Descendents("CreditCardNumber")
                        select creditCardNode.Value).ToArray<string>();
-6
ответ дан 24 November 2019 в 12:13
поделиться

Думаю, я нашел то, что искал. В следующем коде вы можете видеть, что я выполняю оценку Element.Name.LocalName == "CreditCardNumber" . В моих тестах это, похоже, сработало. Я не уверен, что это лучшая практика, но я собираюсь ее использовать.

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

Теперь у меня есть элементы, в которых я могу зашифровать значения.

Если у кого-то есть лучшее решение, пожалуйста, предоставьте его. Спасибо.

13
ответ дан 24 November 2019 в 12:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: