I have this XML input:
<?xml version="1.0"?>
<xc:XmlCache xmlns:xc="XmlCache" xmlns:mp="mx.MarketParameters" xmlns:rt="mx.MarketParameters.Rates" xmlns:rtcu="mx.MarketParameters.Rates.Curve">
<xc:XmlCacheArea xc:value="MarketParameters">
<mp:nickName xmlns:mp="mx.MarketParameters" xc:value="BO">
<mp:date xc:value="20211208">
<rt:rate xmlns:rt="mx.MarketParameters.Rates">
<rtcu:curve xmlns:rtcu="mx.MarketParameters.Rates.Curve">
<rtcu:currency xc:value="USD">
<rtcu:label xc:value="USD: SOV_ZC">
<rtcu:type xc:value="Swap">
<rtcu:generator xc:value="USD S TREAS">
<rtcu:market xc:value="">
<rtcu:maturity xc:value="10Y" xc:dates="20211210-20311210" xc:type="Fields">
<mp:askConvexitySpread xc:keyFormat="N">0</mp:askConvexitySpread>
<mp:askCurveSpread xc:keyFormat="N">0.000000000</mp:askCurveSpread>
<mp:askDiscount xc:keyFormat="N">0.864632927818374</mp:askDiscount>
<mp:askDiscountBasisSpread xc:keyFormat="N"/>
<mp:askMarketQuote xc:keyFormat="N">1.446068284</mp:askMarketQuote>
<mp:askZeroCoupon xc:keyFormat="N">1.45291000006736</mp:askZeroCoupon>
<mp:askZeroCouponBasisSpread xc:keyFormat="N"/>
<mp:askZeroCouponSpread xc:keyFormat="N">0.000000000</mp:askZeroCouponSpread>
<mp:bidConvexitySpread xc:keyFormat="N">0</mp:bidConvexitySpread>
<mp:bidCurveSpread xc:keyFormat="N">0.000000000</mp:bidCurveSpread>
<mp:bidDiscount xc:keyFormat="N">0.864632927818374</mp:bidDiscount>
<mp:bidDiscountBasisSpread xc:keyFormat="N"/>
<mp:bidMarketQuote xc:keyFormat="N">1.446068284</mp:bidMarketQuote>
<mp:bidZeroCoupon xc:keyFormat="N">1.45291000006736</mp:bidZeroCoupon>
<mp:bidZeroCouponBasisSpread xc:keyFormat="N"/>
<mp:bidZeroCouponSpread xc:keyFormat="N">0.000000000</mp:bidZeroCouponSpread>
<mp:frontierDate xc:keyFormat="N">0</mp:frontierDate>
<mp:intervalSplineEta xc:keyFormat="N">-1</mp:intervalSplineEta>
<mp:midConvexitySpread xc:keyFormat="N">0</mp:midConvexitySpread>
<mp:midCurveSpread xc:keyFormat="N">0.000000000</mp:midCurveSpread>
<mp:midDiscount xc:keyFormat="N">0.864632927818374</mp:midDiscount>
<mp:midDiscountBasisSpread xc:keyFormat="N"/>
<mp:midMarketQuote xc:keyFormat="N">1.446068284</mp:midMarketQuote>
<mp:midZeroCoupon xc:keyFormat="N">1.45291000006736</mp:midZeroCoupon>
<mp:midZeroCouponBasisSpread xc:keyFormat="N"/>
<mp:midZeroCouponSpread xc:keyFormat="N">0.000000000</mp:midZeroCouponSpread>
<mp:selected xc:keyFormat="N">1</mp:selected>
</rtcu:maturity>
<rtcu:maturity xc:value="15Y" xc:dates="20211210-20361210" xc:type="Fields">
<mp:askConvexitySpread xc:keyFormat="N">0</mp:askConvexitySpread>
<mp:askCurveSpread xc:keyFormat="N">0.000000000</mp:askCurveSpread>
<mp:askDiscount xc:keyFormat="N">0.769521955887512</mp:askDiscount>
<mp:askDiscountBasisSpread xc:keyFormat="N"/>
<mp:askMarketQuote xc:keyFormat="N">1.716406662</mp:askMarketQuote>
<mp:askZeroCoupon xc:keyFormat="N">1.74466000012162</mp:askZeroCoupon>
<mp:askZeroCouponBasisSpread xc:keyFormat="N"/>
<mp:askZeroCouponSpread xc:keyFormat="N">0.000000000</mp:askZeroCouponSpread>
<mp:bidConvexitySpread xc:keyFormat="N">0</mp:bidConvexitySpread>
<mp:bidCurveSpread xc:keyFormat="N">0.000000000</mp:bidCurveSpread>
<mp:bidDiscount xc:keyFormat="N">0.769521955887512</mp:bidDiscount>
<mp:bidDiscountBasisSpread xc:keyFormat="N"/>
<mp:bidMarketQuote xc:keyFormat="N">1.716406662</mp:bidMarketQuote>
<mp:bidZeroCoupon xc:keyFormat="N">1.74466000012162</mp:bidZeroCoupon>
<mp:bidZeroCouponBasisSpread xc:keyFormat="N"/>
<mp:bidZeroCouponSpread xc:keyFormat="N">0.000000000</mp:bidZeroCouponSpread>
<mp:frontierDate xc:keyFormat="N">0</mp:frontierDate>
<mp:intervalSplineEta xc:keyFormat="N">-1</mp:intervalSplineEta>
<mp:midConvexitySpread xc:keyFormat="N">0</mp:midConvexitySpread>
<mp:midCurveSpread xc:keyFormat="N">0.000000000</mp:midCurveSpread>
<mp:midDiscount xc:keyFormat="N">0.769521955887512</mp:midDiscount>
<mp:midDiscountBasisSpread xc:keyFormat="N"/>
<mp:midMarketQuote xc:keyFormat="N">1.716406662</mp:midMarketQuote>
<mp:midZeroCoupon xc:keyFormat="N">1.74466000012162</mp:midZeroCoupon>
<mp:midZeroCouponBasisSpread xc:keyFormat="N"/>
<mp:midZeroCouponSpread xc:keyFormat="N">0.000000000</mp:midZeroCouponSpread>
<mp:selected xc:keyFormat="N">1</mp:selected>
</rtcu:maturity>
</rtcu:market>
</rtcu:generator>
</rtcu:type>
</rtcu:label>
</rtcu:currency>
</rtcu:curve>
</rt:rate>
</mp:date>
</mp:nickName>
</xc:XmlCacheArea>
</xc:XmlCache>
I am using this transform :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mp="mx.MarketParameters" xmlns:xc="xmlCache" xmlns:rt="mx.MarketParameters.Rates" xmlns:rtcu="mx.MarketParameters.Rates.Curve">
<xsl:template match="/">
<data>
<xsl:apply-templates select="*"/>
</data>
</xsl:template>
<xsl:template match="rtcu:maturity">
<row>
<xsl:attribute name="Cle"><xsl:value-of select="../../../../../@*:value"/>;<xsl:value-of select="../../../../@*:value"/>;<xsl:value-of select="../../../@*:value"/>;<xsl:value-of select="../../@*:value"/>;<xsl:value-of select="../@*:value"/>;<xsl:value-of select="@*:value"/></xsl:attribute>
<xsl:attribute name="Source1"><xsl:value-of select="mp:askZeroCoupon"/></xsl:attribute>
<xsl:attribute name="Source2"><xsl:value-of select="mp:bidZeroCoupon"/></xsl:attribute>
<xsl:attribute name="Source3"><xsl:value-of select="mp:midZeroCoupon"/></xsl:attribute>
</row>
</xsl:template>
</xsl:stylesheet>
And the result is as expected when I use the validator here: https://www.freeformatter.com/xsl-transformer.html
<data xmlns:mp="mx.MarketParameters"
xmlns:xc="xmlCache"
xmlns:rt="mx.MarketParameters.Rates"
xmlns:rtcu="mx.MarketParameters.Rates.Curve">
<row Cle="USD;USD: SOV_ZC;Swap;USD S TREAS;;10Y"
Source1="1.45291000006736"
Source2="1.45291000006736"
Source3="1.45291000006736"/>
<row Cle="USD;USD: SOV_ZC;Swap;USD S TREAS;;15Y"
Source1="1.74466000012162"
Source2="1.74466000012162"
Source3="1.74466000012162"/>
</data>
However when I run this transform in a C# app and call the Load() function in XslCompiledTransform when I pass it this transform above, it fails with the error
Expected end of the expression, found `':'.\r\n../../../../../@* -->:<--`
It basically refuses to check the other namespaces for the attribute I'm looking for on this node.
I know that the attributes are in the xc namespace but when I use the xc: namespace to get the attribute values to build my key like so:
<xsl:value-of select="@xc:value"/>
The values are all null which results in a key that looks like this in the output:
<row Cle=";;;;;"
No bueno!
How can I output the values of all the xc:value attributes from these tags:
<rtcu:currency xc:value="USD">
<rtcu:label xc:value="USD: SOV_ZC">
<rtcu:type xc:value="Swap">
<rtcu:generator xc:value="USD S TREAS">
<rtcu:market xc:value="">
<rtcu:maturity xc:value="10Y"
into my key row:
<row Cle="USD;USD: SOV_ZC;Swap;USD S TREAS;;10Y"
while not triggering a parsing error in the c# Load() function?
CodePudding user response:
There are two errors in your code:
Namespace wildcards like
*:value
are a feature of XPath-2.0 and aboveLocal name tests (namespace wildcards) were eventually added to XPath 2.0
So you can't use them in your XSLT-1.0 code
You have a typo in your
xc:
namespace declaration:- In your XML it's
xmlns:xc="XmlCache"
- In your XSLT it's
xmlns:xc="xmlCache"
- In your XML it's
If you fix both, the code should work as desired.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:mp="mx.MarketParameters" xmlns:xc="XmlCache" xmlns:rt="mx.MarketParameters.Rates" xmlns:rtcu="mx.MarketParameters.Rates.Curve">
<xsl:template match="/">
<data>
<xsl:apply-templates select="*"/>
</data>
</xsl:template>
<xsl:template match="rtcu:maturity">
<row>
<xsl:attribute name="Cle"><xsl:value-of select="../../../../../@xc:value"/>;<xsl:value-of select="../../../../@xc:value"/>;<xsl:value-of select="../../../@xc:value"/>;<xsl:value-of select="../../@xc:value"/>;<xsl:value-of select="../@xc:value"/>;<xsl:value-of select="@xc:value"/></xsl:attribute>
<xsl:attribute name="Source1"><xsl:value-of select="mp:askZeroCoupon"/></xsl:attribute>
<xsl:attribute name="Source2"><xsl:value-of select="mp:bidZeroCoupon"/></xsl:attribute>
<xsl:attribute name="Source3"><xsl:value-of select="mp:midZeroCoupon"/></xsl:attribute>
</row>
</xsl:template>
</xsl:stylesheet>
BTW you can simplify one of your expressions to
<xsl:attribute name="Cle"><xsl:for-each select="ancestor-or-self::rtcu:*"><xsl:value-of select="@xc:value"/><xsl:if test="position()!=last() and position()!=1">;</xsl:if></xsl:for-each></xsl:attribute>
This concatenates the xc:value
attributes of all rtcu:*
ancestors. Maybe that's of some use to you.