简体   繁体   中英

XSLT 2.0 error handling: throw exception to javascript

I have an input XML File:

<Items>
    <Item Name="1" Value="Value1"></Item>
    <Item Name="2" Value="Value2"></Item>
</Items>

What I want to transform to following output file with Saxon-CE.

<Items>
    <Item Name="1" Value="NewValue1"></Item>
    <Item Name="2" Value="NewValue2"></Item>
</Items>

JS:

function TransformXML() {
    xsltData = Saxon.requestXML("transformXML.xsl");
    xmlData = Saxon.requestXML("myxml.xml");
    var xsltProcessor = Saxon.newXSLT20Processor(xsltData);
    var result = xsltProcessor.transformToDocument(xmlData);
    }

I have a mapping, that tells me the value of an item and the NewValue it should have after the transformation. What I have so far:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">                    

    <xsl:strip-space elements="*" />
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" name="xml" />

    <xsl:variable name="Items">
        <Item Name="1">
            <Value OldValue="Value1" NewValue="NewValue1" ></Value>
        </Item>
        <Item Name="2">
            <Value OldValue="Value2" NewValue="NewValue2" ></Value>
        </Item>
    </xsl:variable>

    <xsl:template match="Items">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>   

    <xsl:template match="Item">
        <xsl:copy>
            <xsl:if test="not($Items/Item[@Name=current()/@Name]/Value[@OldValue = current()/@Value])">
                <!-- if value mismatch throw exception and stop -->
            </xsl:if>
            <xsl:attribute name="Value">                    
                <xsl:value-of select="$Items/Item[@Name=current()/@Name]/Value[@OldValue = current()/@Value]/@NewValue"/>
            </xsl:attribute>
            <xsl:copy-of select="@*[name()!= 'Value']" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

This is working, but what I want to do now is to check if there is a value mismatch. If yes then the script should stop and throw an exception what I can catch in the Javascript function. Is there a way to realize this? Can I set a callback function for this?

With XSLT, you can terminate processing using <xsl:message select="'some message'" terminate="yes"/> . It would be desirable that the transformToDocument method throws a Javascript exception you could catch with try/catch but it does not seem to happen, at least not in a quick test I did. I was however able to set an error handler and handle that message in that handler, see http://home.arcor.de/martin.honnen/xslt/test2014120301.html for an example, which does

function onSaxonLoad()
{
  Saxon.setLogLevel('SEVERE');
  var errors = [];
  Saxon.setErrorHandler(function(error) { errors.push(error); });

  var xslt = Saxon.requestXML("test2014120301.xsl")
  var xsltProc = Saxon.newXSLT20Processor(xslt);

  xsltProc.setInitialTemplate("main");

  var errorCount = errors.length;
  var doc = xsltProc.transformToDocument();
  if (errorCount < errors.length) {
    var msg = errors[errors.length - 1].message;
    var pre = document.createElement('pre');
    pre.textContent = msg;
    document.body.appendChild(pre);
  }
  else {
    // use result document doc here
  }      

}

The message Saxon pushes to the error handler is SEVERE: XPathException in invokeTransform: Processing terminated by xsl:message in test2014120301.xsl . Obviously there could be other errors pushed to the error handler so you will need more checks on the Javascript side to perhaps check that the message test contains Processing terminated by xsl:message .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM