views:

28

answers:

2

Here is part of the xml I am trying to parse:

<?xml version="1.0" encoding="UTF-8"?>
<Workflow xmlns="http://soap.sforce.com/2006/04/metadata"&gt;
    <alerts>
        <fullName>Broker_Not_In_SF_Current_Broker_Account</fullName>
        <description>Broker Not In SF - Current Broker Account</description>
        <protected>false</protected>
        <recipients>
            <recipient>[email protected]</recipient>
            <type>user</type>
        </recipients>
        <senderType>CurrentUser</senderType>
        <template>Broker_Emails/Current_Broker_on_Acct_Not_in_SF</template>
    </alerts>
    <rules>
        <fullName>No Service Contact Assigned</fullName>
        <active>true</active>
        <criteriaItems>
            <field>Account.Type</field>
            <operation>equals</operation>
            <value>Client</value>
        </criteriaItems>
        <criteriaItems>
            <field>Account.Service_Contact__c</field>
            <operation>equals</operation>
        </criteriaItems>
        <description>Notification when a service contact has not been assigned after 5 days, then 8 days.</description>
        <triggerType>onCreateOrTriggeringUpdate</triggerType>
    </rules>
</Workflow>

I can use simple Linq to XML on some random SIMPLE XML file, but In this instance I get nothing. I assume because of the xml namespace, but is there a way around this other than removing that in the xml rile prior to parsing?

I haven't done much XML work in the past, so I'm trying to understand the best way that I can take a file like shown and pull out the rule nodes to create a collection or rules with properties. I can get the object/collection part, but I'm stuck on WHY the namespace is failing this simple call:

var setting = xmlDoc.Descendants("rules").First(e => e.Element("fullName").Value == "No Service Contact Assigned");
Console.WriteLine(setting.Element("active").Value); 

Thanks for any help on what to do about this or how to properly use the namespace.

+1  A: 

You need an XNamespace like this:

XNamespace ns = "http://soap.sforce.com/2006/04/metadata";
var setting = xmlDoc.Root.Descendants(ns+"rules").First(e => e.Element(ns+"fullName").Value == "No Service Contact Assigned");
Console.WriteLine(setting.Element(ns+"active").Value); 

Note that the document is not the root node (e.g. Workflow element), but the Root property on the document is. I also added that.

Lucero
perfect, just the simple thing I figured I was overlooking.
BryanGrimes
Yep, you were very close. Namespaces in XML must always match in order to get the wanted results (not just for LINQ-to-XML, but also in XPath, XSLT, XQuery etc.).
Lucero
And we must remember that the "+" operator is overloaded... this is my first known encounter with operator overloading in the wild...
rasx
+1  A: 

You can do it like this:

        var setting = xmlDoc.Descendants(XName.Get("rules", "http://soap.sforce.com/2006/04/metadata")).First(e => e.Element(XName.Get("fullName", "http://soap.sforce.com/2006/04/metadata")).Value == "No Service Contact Assigned");
        Console.WriteLine(setting.Element(XName.Get("active", "http://soap.sforce.com/2006/04/metadata")).Value);
Richard Hein