开发者

Please help me understand why my XSL Transform is not transforming

I'm trying to transform one XML format to another using XSL. Try as I might, I can't seem to get a result.

I've hacked away at this for a while now and I've had no success. I'm not even getting any exceptions. I'm going to post the entire code and hopefully someone can help me work out what I've done wrong.

I'm aware there are likely to be problems in the xsl I have in terms of selects a开发者_开发百科nd matches, but I'm not fussed about that at the moment.

The output I'm getting is the input XML without any XML tags. The transformation is simply not occurring.


Here's my XML Document:

<?xml version="1.0"?>
<Transactions>
    <Account>
        <PersonalAccount>
            <AccountNumber>066645621</AccountNumber>
            <AccountName>A Smith</AccountName>
            <CurrentBalance>-200125.96</CurrentBalance>
            <AvailableBalance>0</AvailableBalance>
            <AccountType>LOAN</AccountType>
        </PersonalAccount>
    </Account>
    <StartDate>2010-03-01T00:00:00</StartDate>
    <EndDate>2010-03-23T00:00:00</EndDate>
    <Items>
        <Transaction>
            <ErrorNumber>-1</ErrorNumber>
            <Amount>12000</Amount>
            <Reference>Transaction 1</Reference>
            <CreatedDate>0001-01-01T00:00:00</CreatedDate>
            <EffectiveDate>2010-03-15T00:00:00</EffectiveDate>
            <IsCredit>true</IsCredit>
            <Balance>-324000</Balance>
        </Transaction>
        <Transaction>
            <ErrorNumber>-1</ErrorNumber>
            <Amount>11000</Amount>
            <Reference>Transaction 2</Reference>
            <CreatedDate>0001-01-01T00:00:00</CreatedDate>
            <EffectiveDate>2010-03-14T00:00:00</EffectiveDate>
            <IsCredit>true</IsCredit>
            <Balance>-324000</Balance>
        </Transaction>
    </Items>
</Transactions>

Here's my XSLT:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" />
  <xsl:param name="currentdate"></xsl:param>
  <xsl:template match="Transactions">

<xsl:element name="OFX">
    <xsl:element name="SIGNONMSGSRSV1">
        <xsl:element name="SONRS">
            <xsl:element name="STATUS">
                <xsl:element name="CODE">0</xsl:element>
                <xsl:element name="SEVERITY">INFO</xsl:element>
            </xsl:element>
            <xsl:element name="DTSERVER"><xsl:value-of select="$currentdate" /></xsl:element>
            <xsl:element name="LANGUAGE">ENG</xsl:element>
        </xsl:element>
    </xsl:element>
    <xsl:element name="BANKMSGSRSV1">
        <xsl:element name="STMTTRNRS">
            <xsl:element name="TRNUID">1</xsl:element>
            <xsl:element name="STATUS">
                <xsl:element name="CODE">0</xsl:element>
                <xsl:element name="SEVERITY">INFO</xsl:element>
            </xsl:element>
            <xsl:element name="STMTRS">
                <xsl:element name="CURDEF">AUD</xsl:element>
                <xsl:element name="BANKACCTFROM">
                    <xsl:element name="BANKID">RAMS</xsl:element>
                    <xsl:element name="ACCTID"><xsl:value-of select="Account/PersonalAccount/AccountNumber" /></xsl:element>
                    <xsl:element name="ACCTTYPE"><xsl:value-of select="Account/PersonalAccount/AccountType" /></xsl:element>
                </xsl:element>
                <xsl:element name="BANKTRANLIST">
                    <xsl:element name="DTSTART"><xsl:value-of select="StartDate" /></xsl:element>
                    <xsl:element name="DTEND"><xsl:value-of select="EndDate" /></xsl:element>

    <xsl:for-each select="Items/Transaction">
                    <xsl:element name="STMTTRN">
                        <xsl:element name="TRNTYPE"><xsl:choose><xsl:when test="IsCredit">CREDIT</xsl:when><xsl:otherwise>DEBIT</xsl:otherwise></xsl:choose></xsl:element>
                        <xsl:element name="DTPOSTED"><xsl:value-of select="EffectiveDate" /></xsl:element>
                        <xsl:element name="DTUSER"><xsl:value-of select="CreatedDate" /></xsl:element>
                        <xsl:element name="TRNAMT"><xsl:value-of select="Amount" /></xsl:element>
                        <xsl:element name="FITID" />
                        <xsl:element name="NAME"><xsl:value-of select="Reference" /></xsl:element>
                        <xsl:element name="MEMO"><xsl:value-of select="Reference" /></xsl:element>
                    </xsl:element>
    </xsl:for-each>

                </xsl:element>
                <xsl:element name="LEDGERBAL">
                    <xsl:element name="BALAMT"><xsl:value-of select="Account/PersonalAccount/CurrentBalance" /></xsl:element>
                    <xsl:element name="DTASOF"><xsl:value-of select="EndDate" /></xsl:element>
                </xsl:element>
            </xsl:element>
        </xsl:element>
    </xsl:element>
</xsl:element>
  </xsl:template>
</xsl:stylesheet>

Here's my method to transform my XML:

public string TransformToXml(XmlElement xmlElement, Dictionary<string, object> parameters)
{
    string strReturn = "";

    // Load the XSLT Document
    XslCompiledTransform xslt = new XslCompiledTransform();
    xslt.Load(xsltFileName);

    // arguments
    XsltArgumentList args = new XsltArgumentList();
    if (parameters != null && parameters.Count > 0)
    {
        foreach (string key in parameters.Keys)
        {
            args.AddParam(key, "", parameters[key]);
        }
    }

    //Create a memory stream to write to
    Stream objStream = new MemoryStream();

    // Apply the transform
    xslt.Transform(xmlElement, args, objStream);

    objStream.Seek(0, SeekOrigin.Begin);

    // Read the contents of the stream
    StreamReader objSR = new StreamReader(objStream);

    strReturn = objSR.ReadToEnd();

    return strReturn;
}

The contents of strReturn is an XML tag (<?xml version="1.0" encoding="utf-8"?>) followed by a raw dump of the contents of the original XML document, stripped of XML tags.

What am I doing wrong here?


I have verified that the provided transformation when applied with XslCompiledTransform on the provided XML document produces very meaningful (probably the desired) output.

Let me guess: maybe the provided XML is not the same as the one used in practice? Maybe you have a default namespace?

If so, you need to match nodes in the default namespace -- not in "no namespace".

You can easily verify if the XmlElement that you provide is in a namespace: inspect/print its NamespaceURI property.


I found that I needed to couch my transformations in the following template:

<?xml version="1.0" encoding="UTF-8" ?>
<xslt:stylesheet version="1.0"
                 xmlns:xslt="http://www.w3.org/1999/XSL/Transform">
  <xslt:template match="child::*"
                 priority="-1000">
    <xslt:copy>
      <xslt:call-template name="dc_CopyAll" />
    </xslt:copy>
  </xslt:template>

  <xslt:template match="attribute::*"
                 priority="-1000">
    <xslt:attribute namespace="{namespace-uri()}"
                    name="{local-name()}">
      <xslt:value-of select="." />
    </xslt:attribute>
  </xslt:template>

  <xslt:template name="dc_CopyAll">
    <xslt:apply-templates select="attribute::*|child::*" />
  </xslt:template>

  <!-- your transforms would go here -->
</xslt:stylesheet>

The way this works is that there are low priority catch-all templates that trap every node and copy their content while executing the entire body of templates in the transform on each child node. Any template with a priority over -1000 will take precedence.

I honestly don't know if you are going to be helped by this but the problem has the same smell as the problem I was trying to solve when I wrote it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜