#java #xml #xslt
#java #xml #xslt
Вопрос:
В Java при преобразовании одного XML в другой XML с использованием файла XSLT, при вводе неверного XML в качестве входных данных (отрицательное тестирование) исключение TransformerException не генерируется.
Неверный XML вот XML без тегов, который ожидает XSLT Пример неверного XML 123
Снимок XSLT (обратите внимание, что образец нигде не указан тегом здесь)
*<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>*
Ввод
<Sample>202008131228</Sample>
Вывод
<?xml version="1.0" encoding="UTF-8"?>202008131228
Желаемый результат: если у входящего XML нет какого-либо элемента XML, определенного в XSLT. Должно быть сгенерировано исключение (чего не происходит) Нужно знать, почему, и я хочу, чтобы код выдавал исключение в этом случае. Какая логика кода позволила бы этого добиться?
Код просто загружает файл XSLT и преобразует его. Код не переходит в блок исключений. он успешно преобразуется, и строка outputResultStr является результатом выше
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. Использование
xpath-default-namespace="SammpleReply"
предполагает, что вы используете Saxon. Если это Saxon 9.8 или более поздней версии, попробуйте добавить<xsl:mode on-no-match="fail"/>
, см. w3.org/TR/xslt-30/#built-in-templates-fail .2. Любое аналогичное решение, доступное для XSLT 2.0?
3. Смотрите ответ Майкла Кея.
Ответ №1:
В XSLT 1.0 или 2.0 добавьте правило шаблона
<xsl:template match="*">
<xsl:message terminate="yes">Unknown element <xsl:value-of select="name()"/></xsl:message>
</xsl:template>
для сопоставления элементов, которые не соответствуют никакому другому правилу шаблона.
В версии 3.0 добавьте <xsl:mode on-no-match="fail"/>
.
Причина, по которой это не сбой, заключается в том, что XSLT определяет правило шаблона по умолчанию для обработки элементов, которым не соответствует ни одно другое правило шаблона в таблице стилей.
Комментарии:
1. Это сработало. Но также можем ли мы выдать ошибку, если во входящем XML отсутствует какой-либо из тегов, как определено в XSLT . Например, « <OrderNumber><xsl:value-of select=»ContextItem/order:OrderID»/></OrderNumber> « если у нас нет идентификатора заказа в xml, можем ли мы выдать ошибку?
2. Один из способов сделать это — использовать преобразование XSLT с поддержкой схемы, с правилами проверки подлинности XML, определенными отдельно в XSD.
Ответ №2:
преобразование xsl пройдет, даже если нет совпадающих тегов.
Есть несколько вариантов …
- реорганизуйте xsl для сопоставления / и найдите желаемые / разрешенные теги и выдайте ошибку, используя
<xsl:message terminate="yes"/>
если не найдено - создайте XML-схему для ввода xml и проверьте перед преобразованием
Комментарии:
1. В логике преобразования, когда он пытается сослаться на исходный тег, а исходный тег не найден в XML, возможно ли в этом случае выдать ошибку?
2. <xsl-if test=»whatever»><xsl: завершение сообщения=»yes»> тег не найден</xsl:message></xsl-if>
3. «независимо» здесь относится к имени исходного тега, я полагаю.
Ответ №3:
Вы можете реализовать SAX schema validation API перед преобразованием XSLT.
Здесь моя программа проверки SAX определяет схему для проверки входных данных XML:
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
Правильно сформированный и действительный XML-файл является:
<?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>
Всего одна проверка может точно перехватить весь диапазон ошибочных входных данных и корректно выйти из приложения.
например: отсутствует тег
</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'.
например: неправильно сформированный элемент / атрибут =>
<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.
например: неправильно сформированный 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.