如何在验证时从不同位置(Jar)读取XSD架构

时间:2017-10-12 10:28:16

标签: jaxb marshalling unmarshalling

我想要编组和解组xsd。我有一个罐子说A.jar包含一个xsd文件,说1.xsd。我试图通过使用JAXB验证它,但它失败了。 1.xsd正在导入另外3个架构,它存在于不同的jar(B. jar)中。我如何验证,在验证它时,1.xsd可以读取属于不同jar(B.jar)的导入文件。

1 个答案:

答案 0 :(得分:0)

假设两个jar都可以在类路径上使用,那么模式文件是否分布在不同的jar上并不重要。如果一个模式导入或包含另一个模式,重要的是可以解析路径。

假设您有var mealsAndSchoolsPerformance = schoolData .Where(s => s.IsHidden == false) .AsParallel()//This causes that following query will run on multiple threads .Select(sc => new MealsAndSchoolPerformanceUI { Id = sc.Id, SchoolName = sc.SchoolName, Week = DateExtensions.GetIso8601WeekOfYear(startDate, true), TotalFoodSpent = foodSpend.ContainsKey(sc.Id) ? foodSpend[sc.Id] : 0, TotalHours = totalHours.ContainsKey(sc.Id) ? totalHours[sc.Id]: 0, MealsKs1 = meals.Where(m => m.SchoolId == sc.Id).Where(m => m.InvoiceMealType == InvoiceMealType.KeyStage1).Sum(s => s.MealNo), MealsKs2 = meals.Where(m => m.SchoolId == sc.Id).Where(m => m.InvoiceMealType == InvoiceMealType.KeyStage2).Sum(s => s.MealNo), MealsNursery = meals.Where(m => m.SchoolId == sc.Id).Where(m => m.InvoiceMealType == InvoiceMealType.Nursery).Sum(s => s.MealNo), MealsStaff = meals.Where(m => m.SchoolId == sc.Id).Where(m => m.InvoiceMealType == InvoiceMealType.Adult).Sum(s => s.MealNo), MealsSenior = meals.Where(m => m.SchoolId == sc.Id).Where(m => m.InvoiceMealType == InvoiceMealType.Senior).Sum(s => s.MealNo), TotalSales = meals.Where(m => m.SchoolId == sc.Id).Sum(m => m.TotalPrice), TotalInvoicePrice = meals.Where(m => m.SchoolId == sc.Id).Sum(m => m.TotalInvoicePrice), Region = sc.SchoolLead?.AddressRegion ?? " ", SchoolGroup = sc.SchoolGroups.FirstOrDefault()?.GroupName ?? "", Manager = sc.ManagerUser?.FullName ?? "", ServiceStarted = sc.ServiceStarted, RollNoNursery = sc.RollNoNursery ?? 0, RollNoSchool = sc.RollNoSchool ?? 0, ServingDays = MealBL.MealServingDays(sc.Id, startDate, startDate.AddDays(6)) }) .ToList(); my.project.schemas中存在的包A.jar。在B.jar该程序包中包含A.jar1.xsd2.xsd的同一个程序包中导入B.jar。如果1.xsd中的导入元素看起来像这样......

<xs:import namespace="https://www.example.com" schemaLocation="2.xsd" />

然后它应该工作。解析器负责定位其他模式,并且由于给定的schemaLocation是相对的,因此解析器会找到它,因为它将不同jar文件中的相同包视为同一位置。

如果有不同的套餐,事情会变得更加复杂。在这种情况下,您需要使用相对路径,该路径可能需要在包层次结构中向上或向下引用以引用正确的文件(例如:additional/2.xsd如果包additional是其成员包my.project.schemas)。另一种选择是use a custom resolver。这使您可以拦截对外部资源的调用并以编程方式解决它们。

最后,请注意SchemaFactory用于创建Schema对象has a method that accepts an array of sources。如果为每个模式文件创建Source并将其全部提供给工厂以创建Schema对象,则可以避免位置问题。实际上,您可以省略schemaLocation属性,因为可以在所有提供的模式中找到必要的引用。

在过去,我曾使用JAXB验证marshallers / unmarshallers,这些marshallers / unmarshallers必须在不同的包之间使用模式,这些模式也可以跨越不同的jar。最后一个解决方案是为工厂方法提供每个模式Source,这是我的首选方法。