获取导致 IIB 中转换错误的 XML 字段值的 XPath
Get XPath for XML Field Value that caused transformation error in IIB
我在 IIB 中有一个消息流,可以将 XML 转换为平面文件 (DFDL) 结构。我对异常处理有一个奇怪的要求。
在转换时,如果任何 XML 字段导致异常(比如转换异常),我必须生成一个 XML 报告,其中包含导致问题的字段的 XPath。生成的 ExceptionList 没有 XPath(在大多数情况下)。
如何在不影响性能的情况下实现这个?
我试过两种方法:
1) Generate XPath for the complete XML payload and compare value
假设我有如下 XML 并且 EmployerAddress(具有值 'XYZ')导致了问题
<ns:Company xmlns:ns="https://company">
<Employer>
<EmployerName>XYZ</EmployerName> /ns:Company[1]/Employer[1]/EmployerName[1]='XYZ'
<EmployerAddress>XYZ</EmployerAddress> /ns:Company[1]/Employer[1]/EmployerAddress[1]='XYZ'
<Employee>
<EmployeeName>ABC</EmployeeName> /ns:Company[1]/Employer[1]/Employee[1]/EmployeeName[1]='ABC'
<Department>ABC</Department> /ns:Company[1]/Employer[1]/Employee[1]/Department[1]='ABC'
</Employee>
</Employer>
</ns:Company>
ExceptionList 包含具有导致错误的值(在大多数情况下)的插入文本。将 XYZ 连接为 ='XYZ' 并在生成的整个 XPath 列表中搜索。
但是这个逻辑有问题,因为 ='XYZ' 也是值 EmployerName,搜索将 return 我超过 1 个 XPaths 其中, 只有 1 个是正确的。
2) Storing checkpoints before every ESQL statement
在执行任何语句之前将 XPath 作为检查点存储在环境树中。成功执行语句后,用 ESQL 语句中涉及的下一个元素覆盖检查点。
这可行,但是这不是编写代码的好方法加上内存和时间消耗是最大的。
任何suggestions/pseudo/code都会有很大帮助。提前致谢!
更新
添加完整的例外列表
ExceptionList
RecoverableException
File:CHARACTER:F:\build\slot3\S1000_P\src\DataFlowEngine\MessageServices\ImbDataFlowNode.cpp
Line:INTEGER:1250
Function:CHARACTER:ImbDataFlowNode::createExceptionList
Type:CHARACTER:ComIbmWSInputNode
Name:CHARACTER:getXPaths#FCMComposite_1_1
Label:CHARACTER:getXPaths.HTTP Input
Catalog:CHARACTER:BIPmsgs
Severity:INTEGER:3
Number:INTEGER:2230
Text:CHARACTER:Node throwing exception
Insert
Type:INTEGER:14
Text:CHARACTER:getXPaths.HTTP Input
RecoverableException
File:CHARACTER:F:\build\slot3\S1000_P\src\DataFlowEngine\PluginInterface\ImbJniNode.cpp
Line:INTEGER:1269
Function:CHARACTER:ImbJniNode::evaluate
Type:CHARACTER:ComIbmXslMqsiNode
Name:CHARACTER:getXPaths#FCMComposite_1_5
Label:CHARACTER:getXPaths.XSL Transform
Catalog:CHARACTER:BIPmsgs
Severity:INTEGER:3
Number:INTEGER:2230
Text:CHARACTER:Caught exception and rethrowing
Insert
Type:INTEGER:14
Text:CHARACTER:getXPaths.XSL Transform
RecoverableException
File:CHARACTER:F:\build\slot3\S1000_P\src\DataFlowEngine\SQLNodeLibrary\ImbComputeNode.cpp
Line:INTEGER:515
Function:CHARACTER:ImbComputeNode::evaluate
Type:CHARACTER:ComIbmComputeNode
Name:CHARACTER:getXPaths#FCMComposite_1_4
Label:CHARACTER:getXPaths.createError
Catalog:CHARACTER:BIPmsgs
Severity:INTEGER:3
Number:INTEGER:2230
Text:CHARACTER:Caught exception and rethrowing
Insert
Type:INTEGER:14
Text:CHARACTER:getXPaths.createError
RecoverableException
File:CHARACTER:F:\build\slot3\S1000_P\src\DataFlowEngine\ImbRdl\ImbRdlStatementGroup.cpp
Line:INTEGER:792
Function:CHARACTER:SqlStatementGroup::execute
Type:CHARACTER:
Name:CHARACTER:
Label:CHARACTER:
Catalog:CHARACTER:BIPmsgs
Severity:INTEGER:3
Number:INTEGER:2488
Text:CHARACTER:Error detected, rethrowing
Insert
Type:INTEGER:5
Text:CHARACTER:.createError.Main
Insert
Type:INTEGER:5
Text:CHARACTER:13.3
Insert
Type:INTEGER:5
Text:CHARACTER:SET OutputRoot.XMLNSC.Output.Casting = CAST(InputRoot.XMLNSC.*:*.Employer.EmployerAddress AS INTEGER);
RecoverableException
File:CHARACTER:F:\build\slot3\S1000_P\src\DataFlowEngine\ImbRdl\ImbRdlTypeCast.cpp
Line:INTEGER:342
Function:CHARACTER:SqlTypeCast::evaluate
Type:CHARACTER:
Name:CHARACTER:
Label:CHARACTER:
Catalog:CHARACTER:BIPmsgs
Severity:INTEGER:3
Number:INTEGER:2521
Text:CHARACTER:Error casting from %3 to %4
Insert
Type:INTEGER:5
Text:CHARACTER:.createError.Main
Insert
Type:INTEGER:5
Text:CHARACTER:13.42
Insert
Type:INTEGER:5
Text:CHARACTER:'XYZ'
Insert
Type:INTEGER:5
Text:CHARACTER:INTEGER
ConversionException
File:CHARACTER:F:\build\slot3\S1000_P\src\CommonServices\ImbUtility.cpp
Line:INTEGER:441
Function:CHARACTER:imbWcsToInt64
Type:CHARACTER:
Name:CHARACTER:
Label:CHARACTER:
Catalog:CHARACTER:BIPmsgs
Severity:INTEGER:3
Number:INTEGER:2595
Text:CHARACTER:Invalid characters
Insert
Type:INTEGER:2
Text:CHARACTER:-1
Insert
Type:INTEGER:5
Text:CHARACTER:S22018
Insert
Type:INTEGER:5
Text:CHARACTER:XYZ
这是我在环境树中生成的错误处理方法
ErrorDetails
Error
Exact
ErrorCode:INTEGER:2595
ExceptionType:CHARACTER:ConversionException
ErrorSeverity:CHARACTER:Error
ErrorDescription:CHARACTER:Error casting character string 'XYZ' to an integer. State = '-1' 'S22018' '0' ''.
ErrorExplanation:CHARACTER:An attempt was made to cast the character string 'XYZ' to an integer, but the string was of the wrong format.
ErrorResponse:CHARACTER:Other messages will give an indication of context of this error.
Parent
ErrorCode:INTEGER:2521
ExceptionType:CHARACTER:RecoverableException
ErrorSeverity:CHARACTER:Error
ErrorDescription:CHARACTER:(.createError.Main, 13.42) : Error casting the value ''XYZ'' to 'INTEGER'.
ErrorExplanation:CHARACTER:An error occurred when casting a value to a different data type. This may be because no conversions exist between the two data types or because the particular value was unsuitable.
ErrorResponse:CHARACTER:Subsequent messages will indicate the context of the error.
使用逻辑 (1),我得到的响应是
<Output>
<CompleteXPath>/ns:Company[1]/Employer[1]/EmployerName[1]|/ns:Company[1]/Employer[1]/EmployerAddress[1]</CompleteXPath>
<FieldName>EmployerName|EmployerAddress</FieldName>
<FieldValue>XYZ|XYZ</FieldValue>
</Output>
While transformation, if any XML field causes an exception (say conversion exception), I've to generate an XML report which will have the XPath of the field causing issue.
这是一项技术要求,并且(正如您所发现的)实施起来可能很困难/成本很高。谁想要这份 XML 报告,他们想用它做什么?
我的建议是:
基于在这方面的 大量 经验
- 使用 XMLNSC 和 XML 架构进行尽可能多的验证。通过在 XSD 中将元素声明为 xs:int(或其他类型的整数),您的示例 'XYZ is not an integer' 很容易被捕获。 XMLNSC 解析器在报告验证错误时始终提供元素的路径。停止为 XMLNSC 可以为您做的事情编写 ESQL!
- 不要试图验证一切。坚持让业务用户(或任何要求此功能的人)给你一份他们关心的清单。编写代码仅验证这些内容。
- 如有必要,请使用 DFDL 解析器捕获错误。同样,DFDL 解析器在报告错误时几乎总是包含问题字段的路径。
- 向业务用户(或要求此功能的任何人)解释说,做任何比这更多的事情都需要自定义代码,这些代码实施起来既昂贵又耗时,难以正确实施且难以维护。
您可能需要编写一些自定义代码以从各种类型的 XMLNSC 和 DFDL 错误消息中提取 XPath。这可能很繁琐,但至少很容易放入公共库中。
我在 IIB 中有一个消息流,可以将 XML 转换为平面文件 (DFDL) 结构。我对异常处理有一个奇怪的要求。
在转换时,如果任何 XML 字段导致异常(比如转换异常),我必须生成一个 XML 报告,其中包含导致问题的字段的 XPath。生成的 ExceptionList 没有 XPath(在大多数情况下)。
如何在不影响性能的情况下实现这个?
我试过两种方法:
1) Generate XPath for the complete XML payload and compare value
假设我有如下 XML 并且 EmployerAddress(具有值 'XYZ')导致了问题
<ns:Company xmlns:ns="https://company">
<Employer>
<EmployerName>XYZ</EmployerName> /ns:Company[1]/Employer[1]/EmployerName[1]='XYZ'
<EmployerAddress>XYZ</EmployerAddress> /ns:Company[1]/Employer[1]/EmployerAddress[1]='XYZ'
<Employee>
<EmployeeName>ABC</EmployeeName> /ns:Company[1]/Employer[1]/Employee[1]/EmployeeName[1]='ABC'
<Department>ABC</Department> /ns:Company[1]/Employer[1]/Employee[1]/Department[1]='ABC'
</Employee>
</Employer>
</ns:Company>
ExceptionList 包含具有导致错误的值(在大多数情况下)的插入文本。将 XYZ 连接为 ='XYZ' 并在生成的整个 XPath 列表中搜索。
但是这个逻辑有问题,因为 ='XYZ' 也是值 EmployerName,搜索将 return 我超过 1 个 XPaths 其中, 只有 1 个是正确的。
2) Storing checkpoints before every ESQL statement
在执行任何语句之前将 XPath 作为检查点存储在环境树中。成功执行语句后,用 ESQL 语句中涉及的下一个元素覆盖检查点。
这可行,但是这不是编写代码的好方法加上内存和时间消耗是最大的。
任何suggestions/pseudo/code都会有很大帮助。提前致谢!
更新
添加完整的例外列表
ExceptionList
RecoverableException
File:CHARACTER:F:\build\slot3\S1000_P\src\DataFlowEngine\MessageServices\ImbDataFlowNode.cpp
Line:INTEGER:1250
Function:CHARACTER:ImbDataFlowNode::createExceptionList
Type:CHARACTER:ComIbmWSInputNode
Name:CHARACTER:getXPaths#FCMComposite_1_1
Label:CHARACTER:getXPaths.HTTP Input
Catalog:CHARACTER:BIPmsgs
Severity:INTEGER:3
Number:INTEGER:2230
Text:CHARACTER:Node throwing exception
Insert
Type:INTEGER:14
Text:CHARACTER:getXPaths.HTTP Input
RecoverableException
File:CHARACTER:F:\build\slot3\S1000_P\src\DataFlowEngine\PluginInterface\ImbJniNode.cpp
Line:INTEGER:1269
Function:CHARACTER:ImbJniNode::evaluate
Type:CHARACTER:ComIbmXslMqsiNode
Name:CHARACTER:getXPaths#FCMComposite_1_5
Label:CHARACTER:getXPaths.XSL Transform
Catalog:CHARACTER:BIPmsgs
Severity:INTEGER:3
Number:INTEGER:2230
Text:CHARACTER:Caught exception and rethrowing
Insert
Type:INTEGER:14
Text:CHARACTER:getXPaths.XSL Transform
RecoverableException
File:CHARACTER:F:\build\slot3\S1000_P\src\DataFlowEngine\SQLNodeLibrary\ImbComputeNode.cpp
Line:INTEGER:515
Function:CHARACTER:ImbComputeNode::evaluate
Type:CHARACTER:ComIbmComputeNode
Name:CHARACTER:getXPaths#FCMComposite_1_4
Label:CHARACTER:getXPaths.createError
Catalog:CHARACTER:BIPmsgs
Severity:INTEGER:3
Number:INTEGER:2230
Text:CHARACTER:Caught exception and rethrowing
Insert
Type:INTEGER:14
Text:CHARACTER:getXPaths.createError
RecoverableException
File:CHARACTER:F:\build\slot3\S1000_P\src\DataFlowEngine\ImbRdl\ImbRdlStatementGroup.cpp
Line:INTEGER:792
Function:CHARACTER:SqlStatementGroup::execute
Type:CHARACTER:
Name:CHARACTER:
Label:CHARACTER:
Catalog:CHARACTER:BIPmsgs
Severity:INTEGER:3
Number:INTEGER:2488
Text:CHARACTER:Error detected, rethrowing
Insert
Type:INTEGER:5
Text:CHARACTER:.createError.Main
Insert
Type:INTEGER:5
Text:CHARACTER:13.3
Insert
Type:INTEGER:5
Text:CHARACTER:SET OutputRoot.XMLNSC.Output.Casting = CAST(InputRoot.XMLNSC.*:*.Employer.EmployerAddress AS INTEGER);
RecoverableException
File:CHARACTER:F:\build\slot3\S1000_P\src\DataFlowEngine\ImbRdl\ImbRdlTypeCast.cpp
Line:INTEGER:342
Function:CHARACTER:SqlTypeCast::evaluate
Type:CHARACTER:
Name:CHARACTER:
Label:CHARACTER:
Catalog:CHARACTER:BIPmsgs
Severity:INTEGER:3
Number:INTEGER:2521
Text:CHARACTER:Error casting from %3 to %4
Insert
Type:INTEGER:5
Text:CHARACTER:.createError.Main
Insert
Type:INTEGER:5
Text:CHARACTER:13.42
Insert
Type:INTEGER:5
Text:CHARACTER:'XYZ'
Insert
Type:INTEGER:5
Text:CHARACTER:INTEGER
ConversionException
File:CHARACTER:F:\build\slot3\S1000_P\src\CommonServices\ImbUtility.cpp
Line:INTEGER:441
Function:CHARACTER:imbWcsToInt64
Type:CHARACTER:
Name:CHARACTER:
Label:CHARACTER:
Catalog:CHARACTER:BIPmsgs
Severity:INTEGER:3
Number:INTEGER:2595
Text:CHARACTER:Invalid characters
Insert
Type:INTEGER:2
Text:CHARACTER:-1
Insert
Type:INTEGER:5
Text:CHARACTER:S22018
Insert
Type:INTEGER:5
Text:CHARACTER:XYZ
这是我在环境树中生成的错误处理方法
ErrorDetails
Error
Exact
ErrorCode:INTEGER:2595
ExceptionType:CHARACTER:ConversionException
ErrorSeverity:CHARACTER:Error
ErrorDescription:CHARACTER:Error casting character string 'XYZ' to an integer. State = '-1' 'S22018' '0' ''.
ErrorExplanation:CHARACTER:An attempt was made to cast the character string 'XYZ' to an integer, but the string was of the wrong format.
ErrorResponse:CHARACTER:Other messages will give an indication of context of this error.
Parent
ErrorCode:INTEGER:2521
ExceptionType:CHARACTER:RecoverableException
ErrorSeverity:CHARACTER:Error
ErrorDescription:CHARACTER:(.createError.Main, 13.42) : Error casting the value ''XYZ'' to 'INTEGER'.
ErrorExplanation:CHARACTER:An error occurred when casting a value to a different data type. This may be because no conversions exist between the two data types or because the particular value was unsuitable.
ErrorResponse:CHARACTER:Subsequent messages will indicate the context of the error.
使用逻辑 (1),我得到的响应是
<Output>
<CompleteXPath>/ns:Company[1]/Employer[1]/EmployerName[1]|/ns:Company[1]/Employer[1]/EmployerAddress[1]</CompleteXPath>
<FieldName>EmployerName|EmployerAddress</FieldName>
<FieldValue>XYZ|XYZ</FieldValue>
</Output>
While transformation, if any XML field causes an exception (say conversion exception), I've to generate an XML report which will have the XPath of the field causing issue.
这是一项技术要求,并且(正如您所发现的)实施起来可能很困难/成本很高。谁想要这份 XML 报告,他们想用它做什么?
我的建议是:
基于在这方面的 大量 经验- 使用 XMLNSC 和 XML 架构进行尽可能多的验证。通过在 XSD 中将元素声明为 xs:int(或其他类型的整数),您的示例 'XYZ is not an integer' 很容易被捕获。 XMLNSC 解析器在报告验证错误时始终提供元素的路径。停止为 XMLNSC 可以为您做的事情编写 ESQL!
- 不要试图验证一切。坚持让业务用户(或任何要求此功能的人)给你一份他们关心的清单。编写代码仅验证这些内容。
- 如有必要,请使用 DFDL 解析器捕获错误。同样,DFDL 解析器在报告错误时几乎总是包含问题字段的路径。
- 向业务用户(或要求此功能的任何人)解释说,做任何比这更多的事情都需要自定义代码,这些代码实施起来既昂贵又耗时,难以正确实施且难以维护。
您可能需要编写一些自定义代码以从各种类型的 XMLNSC 和 DFDL 错误消息中提取 XPath。这可能很繁琐,但至少很容易放入公共库中。