Note that there are some explanatory texts on larger screens.

plurals
  1. POLinq to join tables on XElement.Name = XAttribute("n")
    primarykey
    data
    text
    <p>This is driving me bat-guano crazy! Client data file:</p> <pre><code>&lt;rows&gt; &lt;row&gt; &lt;CustomerID&gt;ABC123&lt;/CustomerID&gt; &lt;PrdcrCd&gt;10&lt;/PrdcrCd&gt; &lt;StrAdr&gt;123 Main St., NW&lt;/StrAdr&gt; &lt;City&gt;Anytown&lt;/City&gt; etc. &lt;/row&gt; &lt;rows&gt; </code></pre> <p>Map file for transforming client data into acceptable input:</p> <pre><code>&lt;SourceEntries&gt; &lt;map&gt; &lt;Field n='CustomerID' m='201' /&gt; &lt;Field n='StrAdr' m='315' /&gt; &lt;Field n='City' m='316' /&gt; &lt;Field n='PrdrCd' m='442' /&gt; etc. &lt;/map&gt; &lt;/SourceEntries&gt; </code></pre> <p>Finally, the template for acceptable input:</p> <pre><code>&lt;template&gt; &lt;Field n='ClientId' id='201' /&gt; &lt;Field n='Street Address' id='315' /&gt; &lt;Field n='City' id='316' /&gt; &lt;Field n='ProducerCode' id='442' /&gt; etc. &lt;/template&gt; </code></pre> <p>So, from the client file XElement name, match the Source Entries attribute value 'n', and get the Source Entires map reference m. Then, use m to match a template element attribute i, retrieve the template name attribute 'n' and create a new XElement tree using that name. </p> <p>Since I'm a noob at Linq, and not particularly adept at XML, I thought I'd start out slowly. Like this:</p> <pre><code>var results = from t1 in clientXm.Elements("row").Descendants() join t2 in sourceEntries.Elements("Field") on t1.Name equals t2.Attributes("n") into xRef select new { (string)xRef.Attributes("n"), (string)xRef.Attributes("m") }; </code></pre> <p>First error, in the join clause at "on t1.Name.LocalName equals" is that Argument type 'string' is not assignable to parameter type 'TKey'. Then, in the select clause, for the two items I'm interested in, I get "Anonymous type projection initializer should be simple name or member access expression." Oh, and of course, the XML file structures are specification requirements, so I can't change any of them.</p> <p>At this point, I'm so freaking confused I don't know whether the world is upside-down, or I'm standing on my head. Can I please buy a clue... or at least a vowel? Any and all help greatly appreciated.</p> <p><strong>EDIT</strong> </p> <p>Using LinqPad, I tried this statement:</p> <pre><code>XElement _clientXml = XElement.Load(@"client.xml"); XElement _sourceEntries = XElement.Load(@"Client_Map.xml"); foreach (XElement clientData in _clientXml.Descendants("row").Descendants()){ IEnumerable&lt;XElement&gt; mapRefs = from mapData in _sourceEntries.Descendants("Field") where clientData.Name.LocalName == (string) mapData.Attribute("n") select mapData; foreach (XElement item in mapRefs){ Console.WriteLine(item.Attribute("m")); } } </code></pre> <p>In LinqPad, this produced a list of "m" values -- just what I'm trying to get at this baby step. BUT the exact same code in VS gives me nothing. When I debug, mapRefs is an empty set when I get to the second foreach. </p> <p>Does this make any sense at all?</p> <p>Thanks Randy</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload