Question

I have a requirement where I need to return an array for a selection that has only one value(in xml), as the data structure that will consume the data expects an array of integers(an array with one element) in its input.

This is how my XML file looks like

<rowset xmlns="urn:schemas-microsoft-com:xml-analysis:rowset">
  <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:saw-sql="urn:saw-sql" targetNamespace="urn:schemas-microsoft-com:xml-analysis:rowset">
    <xsd:complexType name="Row">
      <xsd:sequence>
        <xsd:element name="Column0" type="xsd:string" minOccurs="0" maxOccurs="1" saw-sql:type="varchar" saw-sql:sqlFormula="&quot;F&amp;R Sales, Balances, Exposures and Limits&quot;.&quot;Financial Calendar&quot;.&quot;Month Year Short Name&quot;" saw-sql:displayFormula="&quot;Financial Calendar&quot;.&quot;Month Year Short Name&quot;" saw-sql:aggregationRule="none" saw-sql:aggregationType="nonAgg" saw-sql:tableHeading="Financial Calendar" saw-sql:columnHeading="Month Year Short Name" saw-sql:isDoubleColumn="false" saw-sql:columnID="c29e370c0db340ad7" />
        <xsd:element name="Column1" type="xsd:string" minOccurs="0" maxOccurs="1" saw-sql:type="varchar" saw-sql:sqlFormula=" CASE WHEN &quot;F&amp;R Sales, Balances, Exposures and Limits&quot;.&quot;GRD Product Current&quot;.&quot;GRD Product Level 5 Name&quot; ='Bill financing' THEN 'Deposits' WHEN &quot;F&amp;R Sales, Balances, Exposures and Limits&quot;.&quot;GRD Product Current&quot;.&quot;GRD Product Level 5 Name&quot; IN ('Operating lease','Finance lease') THEN 'Lending' WHEN &quot;F&amp;R Sales, Balances, Exposures and Limits&quot;.&quot;GRD Product Current&quot;.&quot;GRD Product Level 5 Name&quot; ='Hire purchase and equipment loans' THEN 'Fee Based' ELSE &quot;F&amp;R Sales, Balances, Exposures and Limits&quot;.&quot;GRD Product Current&quot;.&quot;GRD Product Level 5 Name&quot; END" saw-sql:displayFormula=" CASE  WHEN &quot;GRD Product Current&quot;.&quot;GRD Product Level 5 Name&quot; = 'Bill financing' THEN 'Deposits' WHEN &quot;GRD Product Current&quot;.&quot;GRD Product Level 5 Name&quot; IN ('Operating lease', 'Finance lease') THEN 'Lending' WHEN &quot;GRD Product Current&quot;.&quot;GRD Product Level 5 Nam" saw-sql:aggregationRule="none" saw-sql:aggregationType="nonAgg" saw-sql:tableHeading="GRD Product Current" saw-sql:columnHeading="Product" saw-sql:isDoubleColumn="false" saw-sql:columnID="c062984f028c318df" />
        <xsd:element name="Column2" type="xsd:double" minOccurs="0" maxOccurs="1" saw-sql:type="double" saw-sql:sqlFormula="&quot;F&amp;R Sales, Balances, Exposures and Limits&quot;.&quot;Balances - Spot&quot;.&quot;Closing Balance&quot;" saw-sql:displayFormula="&quot;Balances - Spot&quot;.&quot;Closing Balance&quot;" saw-sql:aggregationRule="dimAggr" saw-sql:aggregationType="agg" saw-sql:tableHeading="Balances - Spot" saw-sql:columnHeading="Actual" saw-sql:isDoubleColumn="false" saw-sql:columnID="ca1e1d4f511a8bf93" />
        <xsd:element name="Column3" type="xsd:double" minOccurs="0" maxOccurs="1" saw-sql:type="double" saw-sql:sqlFormula="(&quot;F&amp;R Sales, Balances, Exposures and Limits&quot;.&quot;Balances - Spot&quot;.&quot;Closing Balance&quot;)*1.5" saw-sql:displayFormula="&quot;Balances - Spot&quot;.&quot;Closing Balance&quot; * 1.5" saw-sql:aggregationRule="complex" saw-sql:aggregationType="agg" saw-sql:tableHeading="Balances - Spot" saw-sql:columnHeading="Forecast" saw-sql:isDoubleColumn="false" saw-sql:columnID="ca00747c911de130f" />
        <xsd:element name="Column4" type="xsd:double" minOccurs="0" maxOccurs="1" saw-sql:type="double" saw-sql:sqlFormula="&quot;F&amp;R Sales, Balances, Exposures and Limits&quot;.&quot;Limits&quot;.&quot;Limit Amount&quot;*2" saw-sql:displayFormula="&quot;Limits&quot;.&quot;Limit Amount&quot; * 2" saw-sql:aggregationRule="complex" saw-sql:aggregationType="agg" saw-sql:tableHeading="Balances - Spot" saw-sql:columnHeading="Target" saw-sql:isDoubleColumn="false" saw-sql:columnID="c88758b2e449f89d0" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:schema>
  <Row>
    <Column0>Sep-13</Column0>
    <Column1>Deposits</Column1>
    <Column2>330393232.5</Column2>
    <Column3>495589848.75</Column3>
    <Column4>703232974</Column4>
  </Row>
  <Row>
    <Column0>Sep-13</Column0>
    <Column1>Fee Based</Column1>
    <Column2>111868709.42</Column2>
    <Column3>167803064.13</Column3>
    <Column4>703232974</Column4>
  </Row>
  <Row>
    <Column0>Sep-13</Column0>
    <Column1>Lending</Column1>
    <Column2>18146873.33</Column2>
    <Column3>27220309.995</Column3>
    <Column4>703232974</Column4>
  </Row>
</rowset>

I was trying to do something like this to convert the value to an array of integers.

  var  resultSet = (xmlDoc.Root.Descendants(ns + "Row").Select(result => new
            {
                MonthYearShortName = (DateTime) result.Element(ns + "Column0"),
                Product = (String) result.Element(ns + "Column1"),
                Actual = (decimal) result.Element(ns + "Column2"),
                Forecast = (decimal) result.Element(ns + "Column3"),
                Target = result.Elements(ns + "Column4").Select(s => Convert.ToDecimal(s.FirstNode)).ToArray()
            }));

I get an exception due to the conversion base {System.SystemException} = {"Unable to cast object of type 'System.Xml.Linq.XText' to type 'System.IConvertible'."}

Était-ce utile?

La solution

Cast to decimal instead of using Convert.ToDecimal within Select method:

var resultSet = (xmlDoc.Root.Descendants(ns + "Row").Select(result => new
{
    MonthYearShortName = (DateTime)result.Element(ns + "Column0"),
    Product = (String)result.Element(ns + "Column1"),
    Actual = (decimal)result.Element(ns + "Column2"),
    Forecast = (decimal)result.Element(ns + "Column3"),
    Target = result.Elements(ns + "Column4").Select(s => (decimal)s).ToArray()
}));

But, this makes sense only when you expect more than one Column4 element to exist. Otherwise, you can just do following:

    Target = (decimal)result.Element(ns + "Column4")

or to get decimal[] with just one value:

    Target = new []  { (decimal)result.Element(ns + "Column4") }

Autres conseils

Based on your edit, are you expecting multiple Column4 entries? The definition doesn't make it look like that's the case, so this approach should work:

Target = (decimal)result.Element(ns + "Column4")

Otherwise, if you do need an array add a ToString to the FirstNode call.

Target = result.Elements(ns + "Column4").Select(s => Convert.ToDecimal(s.FirstNode.ToString())).ToArray()

That said, it's not clear why you took a different route with the FirstNode approach. This should work instead and seems clearer to me:

Target = result.Elements(ns + "Column4").Select(s => (decimal)s).ToArray()
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top