In Java wird beim Transformieren eines XML in ein anderes XML mithilfe einer XSLT-Datei keine TransformerException ausgelöst, wenn ein falsches XML als Eingabe angegeben wird (negativer Test).

Bad XML ist hier ein XML ohne Tags, das XSLT erwartet. Beispiel für Bad XML 123

XSLT-Snapshot (Hinweis Beispiel ist kein hier angegebenes Tag)

 *<xsl:template match="/SammpleReply" xpath-default-namespace="SammpleReply" exclude-result-prefixes="#all">
       <RadialReply xmlns="http://SammpleReply.com">
            <xsl:choose>
                <xsl:when test="PaymentContextBase">
                   <PaymentContextBase>
                       <OrderId><xsl:value-of select="RadialReply/Radial:RadialReplySessionId"/></OrderId>
                   </PaymentContextBase>
                   <TenderType><xsl:value-of select="RadialReply/Radial:TenderType"/></TenderType>
                </xsl:when>
               <xsl:otherwise>
                    <RadialReplyContext>
                        <OrderId><xsl:value-of select="RadialContext/payment:RadialUniqueId"/></OrderId>
                         <xsl:element name="RadialUniqueId" >
                            <xsl:attribute name="isToken"><xsl:value-of select="RadialContext/payment:PaymentAccountUniqueId/@isToken"/></xsl:attribute>
                            <xsl:value-of select="RadialContext/payment:RadialUniqueId"/>
                         </xsl:element>
                    </RadialReplyContext>
                   <TenderType><xsl:value-of select="PaymentContext/payment:TenderType"/></TenderType>
               </xsl:otherwise>
            </xsl:choose>
            <SlotsAvailable><xsl:value-of select="SlotsAvailability"/></SlotsAvailable>
           <xsl:choose>
                <xsl:when test="Reattempt">
                    <ReauthorizationAttempted><xsl:value-of select="ReattemptValue"/></ReauthorizationAttempted>
                </xsl:when>
           </xsl:choose>
       </RadialReply>*

Eingang

<Sample>202008131228</Sample>

Ausgabe

<?xml version="1.0" encoding="UTF-8"?>202008131228

Gewünschtes Ergebnis: Wenn für ein eingehendes XML kein XML-Element in XSLT definiert ist. Eine Ausnahme sollte ausgelöst werden (was nicht geschieht). Sie müssen wissen, warum und ich möchte, dass der Code in diesem Fall eine Ausnahme auslöst. Welche Codelogik würde das erreichen? Code lädt nur die XSLT-Datei und transformiert sie. Code geht nicht zum Ausnahmeblock. Es wird erfolgreich transformiert und String outputResultStr ist die obige Ausgabe

 Reader xmlReader = new StringReader(payloadStr);
                StringWriter stringWriter = new StringWriter();
                Result result = new StreamResult(stringWriter);
                transformer.transform(new StreamSource(xmlReader), result);
                outputResultStr = stringWriter.toString();
                

            } catch (TransformerException trEx) {
                  } 
1
Shatz 13 Aug. 2020 im 16:40

3 Antworten

Beste Antwort

Fügen Sie in XSLT 1.0 oder 2.0 eine Vorlagenregel hinzu

<xsl:template match="*">
  <xsl:message terminate="yes">Unknown element <xsl:value-of select="name()"/></xsl:message>
</xsl:template>

Um Elemente abzugleichen, die mit keiner anderen Vorlagenregel übereinstimmen.

Fügen Sie in 3.0 <xsl:mode on-no-match="fail"/> hinzu.

Der Grund, warum dies nicht fehlschlägt, ist, dass XSLT eine Standardvorlagenregel definiert, um Elemente zu verarbeiten, die mit keiner anderen Vorlagenregel im Stylesheet übereinstimmen.

2
Michael Kay 13 Aug. 2020 im 15:39

Die xsl-Transformation wird auch dann bestanden, wenn keine übereinstimmenden Tags vorhanden sind.

Es gibt mehrere Möglichkeiten ...

  • Refactor xsl so, dass es mit / übereinstimmt und nach gewünschten / erlaubten Tags sucht und Fehler mit <xsl:message terminate="yes"/> auslöst, wenn nicht gefunden
  • Erstellen Sie ein XML-Schema für die Eingabe von XML und überprüfen Sie es vor der Transformation
0
Marc Ströbel 13 Aug. 2020 im 13:47

Sie können die SAX-Schemaüberprüfungs-API vor der XSLT-Umwandlung implementieren.

Hier gibt mein SAX-Validierungsprogramm das Schema zur Validierung von XML-Eingabedaten an:

    SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

    InputSourceHandle saxHandle = new InputSourceHandle();
    
    saxHandle.setErrorHandler(new InputSourceHandle.DraconianErrorHandler());
            
    String procSchema =
          "<?xml version='1.0' encoding='UTF-8'?>" +
          "<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' " +
              "xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
              "xsi:schemaLocation='http://www.w3.org/2001/XMLSchema XMLSchema.xsd'>" +
            "<xs:element name='ProcedureDocument'>" +
              "<xs:complexType mixed='true'>" +
                "<xs:choice minOccurs='0' maxOccurs='unbounded'>" +
                  "<xs:element name='title'/>" +
                  "<xs:element name='confidentialityCode'/>" +
                  "<xs:element name='originalText'/>" +
                  "<xs:element name='statusCode'/>" +                     
                  "<xs:element name='methodCode'/>" +
                  "<xs:element name='reference'/>" +
                "</xs:choice>" +
                "<xs:attribute name=\"value\" type='xs:string' use='optional'/>" +
              "</xs:complexType>" +
            "</xs:element>" +
          "</xs:schema>";

    Schema schema = factory.newSchema(new StreamSource(new StringReader(procSchema)));

saxHandle.setDefaultWriteSchema(schema);
…….
//proceed XSLT transformation

Eine wohlgeformte und gültige XML-Datei ist:

<?xml version="1.0" encoding="utf-8"?>
</ProcedureDocument>
    <title>Procedures Anesthesia</title>
    <confidentialityCode>Confidential</confidentialityCode>
    <originalText>Cardiac Surgery :: CABG, arterial, three</originalText>
    <statusCode code="performed"/>
    <methodCode>UNK</methodCode>
    <reference value="#Procedure2"/>
</ProcedureDocument>

Mit nur einer Validierung können alle fehlerhaften Eingaben genau erfasst und die Anwendung ordnungsgemäß beendet werden.

Beispiel: fehlendes Tag </ProcedureDocument>

Error 
   Error reported by XML parser processing null: cvc-elt.1: Cannot find the declaration of
  element 'title'.: cvc-elt.1: Cannot find the declaration of element 'title'.

Beispiel: schlecht geformtes Element / Attribut => <reference Value="#Procedure2"/>

Error 
   Error reported by XML parser processing null: The markup in the document preceding the
  root element must be well-formed.: The markup in the document preceding the root element
  must be well-formed.

Beispiel: schlecht geformter xpath / tag =>

ProcedureDocument
    <title>Procedures Anesthesia</title>
Error 
   Error reported by XML parser processing null: Content is not allowed in prolog.: Content
  is not allowed in prolog.
0
Fiona Chen 19 Aug. 2020 im 03:59