Delphi XE2 XML数据绑定向导导入多XSD时生成XML缺命名空间前缀问题
Delphi XE2 XML Data Binding Wizard导入XSD后命名空间前缀缺失问题
问题描述
使用Delphi XE2的XML Data Binding Wizard时,若主XSD文件包含导入的外部XSD,生成的XML中引用导入XSD定义的节点不会携带对应命名空间前缀,导致XML无法通过校验。
相关代码示例
包含导入规则的主XSD开头片段
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:inv="http://www.aade.gr/myDATA/invoice/v1.0" xmlns:icls="https://www.aade.gr/myDATA/incomeClassificaton/v1.0" xmlns:ecls="https://www.aade.gr/myDATA/expensesClassificaton/v1.0" targetNamespace="http://www.aade.gr/myDATA/invoice/v1.0" elementFormDefault="qualified" version="1.0.3"> <xs:import namespace="https://www.aade.gr/myDATA/incomeClassificaton/v1.0" schemaLocation="incomeClassification-v1.0.3.xsd"/> <xs:import namespace="https://www.aade.gr/myDATA/expensesClassificaton/v1.0" schemaLocation="expensesClassification-v1.0.3.xsd"/>
工具生成的错误XML示例
<?xml version="1.0"?> <!--XML document created with Delphi XE2 by Three Plus Ltd--> <InvoicesDoc xmlns="http://www.aade.gr/myDATA/invoice/v1.0" xmlns:icls="https://www.aade.gr/myDATA/incomeClassificaton/v1.0" xmlns:ecls="https://www.aade.gr/myDATA/expensesClassificaton/v1.0"> <invoice> <uid>1</uid> <mark>240254</mark> <issuer> <vatNumber>084110672</vatNumber> <country>GR</country> <branch>0</branch> </issuer> <counterpart> <vatNumber>052354924</vatNumber> <country>GR</country> <branch>0</branch> <address> <postalCode></postalCode> <city>ΑΓΙΑ ΒΑΡΒΑΡΑ</city> </address> </counterpart> <invoiceHeader> <series>Β</series> <aa>59</aa> <issueDate>2021-01-07</issueDate> <invoiceType>1.1</invoiceType> <currency>EUR</currency> </invoiceHeader> <paymentMethods> <paymentMethodDetails> <type>3</type> <amount>254.68</amount> </paymentMethodDetails> </paymentMethods> <invoiceDetails> <lineNumber>1</lineNumber> <netValue>205.39</netValue> <vatCategory>1</vatCategory> <vatAmount>49.29</vatAmount> <incomeClassification> <classificationType>E3_561_001</classificationType> <classificationCategory>category1_1</classificationCategory> <amount>205.39</amount> </incomeClassification> </invoiceDetails> <invoiceSummary> <totalNetValue>205.39</totalNetValue> <totalVatAmount>49.29</totalVatAmount> <totalWithheldAmount>0.00</totalWithheldAmount> <totalFeesAmount>0.00</totalFeesAmount> <totalStampDutyAmount>0.00</totalStampDutyAmount> <totalOtherTaxesAmount>0.00</totalOtherTaxesAmount> <totalDeductionsAmount>0.00</totalDeductionsAmount> <totalGrossValue>254.68</totalGrossValue> <incomeClassification> <classificationType>E3_561_001</classificationType> <classificationCategory>category1_1</classificationCategory> <amount>205.39</amount> </incomeClassification> </invoiceSummary> </invoice> </InvoicesDoc>
上述XML无法通过校验,原因是incomeClassification下的节点需要携带icls前缀。
符合校验要求的正确XML示例
<?xml version="1.0"?> <!--XML document created with Delphi XE2 by Three Plus Ltd--> <InvoicesDoc xmlns="http://www.aade.gr/myDATA/invoice/v1.0" xmlns:icls="https://www.aade.gr/myDATA/incomeClassificaton/v1.0" xmlns:ecls="https://www.aade.gr/myDATA/expensesClassificaton/v1.0"> <invoice> <uid>1</uid> <mark>241108</mark> <issuer> <vatNumber>084110672</vatNumber> <country>GR</country> <branch>0</branch> </issuer> <counterpart> <vatNumber>130197574</vatNumber> <country>GR</country> <branch>0</branch> <address> <postalCode>12135</postalCode> <city>ΠΕΡΙΣΤΕΡΙ</city> </address> </counterpart> <invoiceHeader> <series>Β</series> <aa>274</aa> <issueDate>2021-01-16</issueDate> <invoiceType>1.1</invoiceType> <currency>EUR</currency> </invoiceHeader> <paymentMethods> <paymentMethodDetails> <type>5</type> <amount>45.50</amount> </paymentMethodDetails> </paymentMethods> <invoiceDetails> <lineNumber>1</lineNumber> <netValue>36.70</netValue> <vatCategory>1</vatCategory> <vatAmount>8.80</vatAmount> <incomeClassification> <icls:classificationType>E3_561_001</icls:classificationType> <icls:classificationCategory>category1_1</icls:classificationCategory> <icls:amount>36.70</icls:amount> </incomeClassification> </invoiceDetails> <invoiceSummary> <totalNetValue>36.70</totalNetValue> <totalVatAmount>8.80</totalVatAmount> <totalWithheldAmount>0.00</totalWithheldAmount> <totalFeesAmount>0.00</totalFeesAmount> <totalStampDutyAmount>0.00</totalStampDutyAmount> <totalOtherTaxesAmount>0.00</totalOtherTaxesAmount> <totalDeductionsAmount>0.00</totalDeductionsAmount> <totalGrossValue>45.50</totalGrossValue> <incomeClassification> <icls:classificationType>E3_561_001</icls:classificationType> <icls:classificationCategory>category1_1</icls:classificationCategory> <icls:amount>36.70</icls:amount> </incomeClassification> </invoiceSummary> </invoice> </InvoicesDoc>
解决方案
可以通过修改向导自动生成的单元代码解决该问题,操作步骤如下:
- 打开向导生成的.pas单元文件,先定位到单元初始化部分的命名空间注册代码,确认
icls、ecls前缀已经和对应命名空间完成绑定,若没有绑定可以手动添加RegisterChildNamespace调用完成映射。 - 找到
incomeClassification下三个子节点classificationType、classificationCategory、amount对应的属性定义代码,这些节点的定义参数中默认会继承主命名空间,手动将其Namespace参数修改为https://www.aade.gr/myDATA/incomeClassificaton/v1.0即可,支出分类相关的节点同理修改为对应ecls的命名空间。 - 修改完成后重新编译项目,生成的XML就会自动为这些节点添加正确的命名空间前缀。如果后续需要重新用向导生成单元,只要备份修改过的节点定义部分,替换新生成的对应代码即可,不需要重复调整全部内容。
内容的提问来源于stack exchange,提问作者Damien Paul
相关产品推荐
相关产品推荐

