当前位置: 首页 > news >正文

公司网站建设费用入账重庆妇科医院排行榜

公司网站建设费用入账,重庆妇科医院排行榜,对文化传播网站建设的建议,wordpress分类页首页调用分类描述上周#xff0c;我被要求用Java编写一些东西#xff0c;该东西能够将单个30GB XML文件拆分为可配置文件大小的较小部分。 该文件的使用者将是一个中间件应用程序#xff0c;该应用程序存在XML较大的问题。 在后台#xff0c;它使用某种DOM解析技术#xff0c;使它在一段时… 上周我被要求用Java编写一些东西该东西能够将单个30GB XML文件拆分为可配置文件大小的较小部分。 该文件的使用者将是一个中间件应用程序该应用程序存在XML较大的问题。 在后台它使用某种DOM解析技术使它在一段时间后耗尽内存。 由于它是基于供应商的中间件因此我们无法自行纠正。 最好的选择是创建一些预处理工具该工具会先将大文件分成多个较小的块然后再由中间件处理。 XML文件带有一个相应的W3C模式该模式由强制性头部分和紧随其后嵌套有多个0 .. *数据元素的内容元素组成。 对于演示代码我以简化形式重新创建了架构 标头的大小可以忽略。 单个数据元素的重复也很小可以说少于50kB。 由于数据元素重复的次数XML太大了。 要求是 分割后的XML的每一部分都应为语法有效的XML并且每一部分还应针对原始模式进行验证 该工具应根据架构验证XML并报告所有验证错误。 验证不得阻塞并且不可在输出中跳过非验证元素或属性 对于标头决定将其复制到每个新的输出文件中而不是将其复制到每个新的输出文件中并使用一些处理信息和一些默认值来重新生成该标头 因此使用诸如Unix Split之类的二进制拆分工具是不可能的。 在固定数量的字节之后这将拆分从而确保XML损坏。 我不太确定但是诸如Split之类的工具也不了解编码。 因此在字节“ x”之后进行拆分不仅会导致在XML元素的中间进行拆分例如而且甚至会在字符编码序列的中间进行拆分例如在使用经过UTF8编码的Unicode时。 显然我们需要更智能的东西。 XSLT作为核心技术也是行不通的。 乍一看可能会很想尝试使用XSLT2.0可以从单个输入文件创建多个输出文件。 甚至可以在转换时验证输入文件。 但是细节始终是魔鬼。 否则在Java中进行简单的操作例如将验证错误写入单独的文件或检查当前输出文件的大小可能需要自定义Java代码。 对于Xalan和Saxon来说当然可以有这样的扩展但是Xalan不是XSLT2.0实现因此只剩下Saxon。 最后但并非最不重要的一点是XSLT1.0 / 2.0是非流式的这意味着它们会将整个源文档读入内存因此这显然将XSLT排除在了可能性之外。 剩下的唯一选择就是Java XML解析。 当然在这种情况下理想的选择是StAX。 我不在这里进行SAX与StAX的比较事实是StAX能够针对架构的身份进行验证至少某些解析器可以并且还可以编写XML。 而且与SAX相比API的使用要容易得多因为基于pull的API提供了对迭代文档的更多控制并且比SAX的推送方式更令人愉快。 好的我们需要什么 能够验证XML的StAX实现 Oracle的JDK默认附带SJSXP作为StAX实现但是此验证无效。 最好具有某种对象/ XML映射技术用于重新创建标头而不是手动摆弄元素并必须查找正确的数据类型/格式 显然是JAXB。 该代码有点大无法在此处整体显示。 可以访问源文件XSD和测试XML 了这里 GitHub上。 它具有Maven pom文件因此您应该能够在选择的IDE中将其导入。 JAXB绑定编译器将自动编译模式并将生成的源放在类路径上。 public void startSplitting() throws Exception {XMLStreamReader2 xmlStreamReader ((XMLInputFactory2) XMLInputFactory.newInstance()).createXMLStreamReader(BigXmlTest.class.getResource(/BigXmlTest.xml));PrintWriter validationResults enableValidationHandling(xmlStreamReader);int fileNumber 0;int dataRepetitions 0;XMLStreamWriter xmlStreamWriter openOutputFileAndWriteHeader(fileNumber); // Prepare first file 第一行创建了StAX流读取器这意味着我们正在使用游标API。 迭代器API使用XMLEventReader类。 类名中还有一个奇怪的“ 2”它表示Woodstox的StAX 2功能其中之一可能是对验证的支持。 从 在这里 StAX2 is an experimental API that is intended to extend basic StAX specifications in a way that allows implementations to experiment with features before they end up in the actual StAX specification (if they do). As such, it is intended to be freely implementable by all StAX implementations same way as StAX, but without going through a formal JCP process. Currently Woodstox is the only known implementation. 可以在“ enableValidationHandling”中看到 源文件如果需要。 我将重点介绍重要的部分。 首先加载XML模式 XMLValidationSchema xmlValidationSchema xmlValidationSchemaFactory.createSchema(BigXmlTest.class.getResource(/BigXmlTest.xsd)); 用于将可能的验证结果写入输出文件的回调 public void reportProblem(XMLValidationProblem validationError) throws XMLValidationException {validationResults.write(validationError.getMessage() Location: ToStringBuilder.reflectionToString(validationError.getLocation(),ToStringStyle.SHORT_PREFIX_STYLE) \r\n);} “ openOutputFileAndWriteHeader”将创建一个XMLStreamWriter它又是游标API的一部分迭代器API具有XMLEventWriter我们可以将其输出或原始XML文件的一部分。 它还将使用JAXB创建我们的标头并将其写入输出。 默认情况下使用Schema编译器xjc生成JAXB对象。 private XMLStreamWriter openOutputFileAndWriteHeader(int fileNumber) throws Exception {XMLOutputFactory xmlOutputFactory XMLOutputFactory.newInstance();xmlOutputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);XMLStreamWriter writer xmlOutputFactory.createXMLStreamWriter(new FileOutputStream(new File(System.getProperty(java.io.tmpdir), BigXmlTest. fileNumber .xml)));writer.setDefaultNamespace(DOCUMENT_NS);writer.writeStartDocument();writer.writeStartElement(DOCUMENT_NS, BIGXMLTEST_ROOT_ELEMENT);writer.writeDefaultNamespace(DOCUMENT_NS);HeaderType header objectFactory.createHeaderType();header.setSomeHeaderElement(Something something darkside);marshaller.marshal(new JAXBElementHeaderType(new QName(DOCUMENT_NS, HEADER_ELEMENT, ), HeaderType.class,HeaderType.class, header), writer);writer.writeStartElement(CONTENT_ELEMENT);return writer;} 在第3行我们启用“修复名称空间”。 规格说明如下 javax.xml.stream.isRepairingNamespaces: Function: Creates default prefixes and associates them with Namespace URIs. Type: Boolean Default Value: False Required: Yes 我从中了解到处理默认名称空间是必需的。 事实是如果未启用则不会以任何方式编写默认名称空间。 在第6行我们设置默认名称空间。 设置它实际上不会将其写入流。 因此需要writeDefaultNamespace第9行但这只能在写入start元素之后才能完成。 因此您必须在编写任何元素之前定义默认名称空间但是您需要在编写第一个元素之后编写默认名称空间。 理由是StAX需要知道它是否必须为要写yes或no的根元素生成前缀。 在第8行我们编写了root元素。 指示此元素所属的名称空间很重要。 如果您未指定前缀则会为您生成一个前缀或者在本例中将不会生成任何前缀因为StAX知道我们已经设置了默认名称空间。 如果您要删除第6行的默认名称空间指示则将为根元素添加前缀带有随机前缀例如wstxns1BigXmlTest xmlnswstxns1 “ http// www ...接下来我们编写默认名称空间它将被写入先前开始的元素顺便说一句为了对此顺序有更深入的了解请参阅这篇不错的文章 在第11-14行中我们使用JAXB生成的模型创建标头然后让我们的JAXB marshaller直接将其写到我们的StAX输出流。 重要提示 JAXB编组器以片段模式初始化否则它将开始添加XML声明这对于独立文档是必需的当然在现有文档中间是不允许的 marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true); 附带说明一下在此示例中JAXB集成并不是真正有用它会增加复杂性并占用更多代码行然后仅使用XMLStreamWriter添加元素即可。 但是如果您有一个更复杂的结构需要创建并合并到文档中则具有自动对象映射非常方便。 因此我们有启用验证的阅读器。 从我们开始遍历源文档的那一刻起它将同时验证和解析。 然后我们的writer已经编写了一个初始化的文档和标头并准备接受更多数据。 最后我们必须遍历源代码并将每个部分写入输出文件。 如果输出文件变大我们将换一个新文件 while (xmlStreamReader.hasNext()) {xmlStreamReader.next();if (xmlStreamReader.getEventType() XMLEvent.START_ELEMENT xmlStreamReader.getLocalName().equals(DATA_ELEMENT)) {if (dataRepetitions ! 0 dataRepetitions % 2 0) { // %2 just for testing: replace this by for example checking the actual size of the current output filexmlStreamWriter.close(); // Also closes any open Element(s) and the documentxmlStreamWriter openOutputFileAndWriteHeader(fileNumber); // Continue with next filedataRepetitions 0;}// Transform the input stream at current position to the output streamtransformer.transform(new StAXSource(xmlStreamReader), new StAXResult(new FragmentXMLStreamWriterWrapper(new AvoidDefaultNsPrefixStreamWriterWrapper(xmlStreamWriter, DOCUMENT_NS))));dataRepetitions;} } 重要的一点是我们不断迭代源文档并检查是否存在Data元素的开头。 如果是这样我们将相应的元素及其同级元素流式传输到输出。 在我们的简单示例中我们没有兄弟姐妹只有文本值。 但是如果结构更复杂则所有基础节点将自动复制到输出中。 每隔两个数据元素我们将循环输出文件。 关闭编写器并初始化一个新的编写器当然可以通过检查文件大小而不是2来代替此检查。 如果作家是关闭的它将自动处理关闭打开的元素并最终关闭文档本身而无需您自己这样做。 作为将节点从输入流传输到输出的机制需要注意以下几点 由于验证我们不得不使用游标API因此必须使用XSLT将节点及其兄弟节点传输到输出。 XSLT具有一些默认模板如果您未专门指定XSL则将调用这些模板。 在这种情况下它将输入转换为给定的输出。 需要一个自定义的FragmentXMLStreamWriterWrapper 我在JavaDoc中对此进行了记录。 再次将这个包装器包装在PreventDefaultNsPrefixStreamWriterWrapper中 。 最后一个原因是默认的XSLT模板无法识别源文档中的默认名称空间。 一分钟内提供更多信息或搜索避免使用DefaultDefaultNsPrefixStreamWriterWrapper。 您使用的转换器必须是Oracle JDK的内部版本。 在初始化转换器的地方我们直接引用内部TransformerFactory的实例 com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl然后创建正确的转换器 Transformer new TransformerFactoryImpl。newTransformer; 通常您将使用TransformerFactory.newInstance并使用classpath上可用的转换器。 但是解析器和转换器可以通过提供META-INF /服务来安装自己。 如果另一个转换器例如默认的Xalan而不是重新打包的JDK版本将在类路径上则转换将失败。 原因是显然只有JDK内部版本才可以从StAXSource转换为StAXResult 转换器实际上将让我们的XMLStreamReader在迭代过程中继续。 因此在处理完一个数据元素之后理论上阅读器的光标将在下一个数据元素处就绪。 从理论上讲如果格式化XML则下一个事件类型可能是空格。 因此在下一个Data元素实际准备就绪之前它仍可能需要在while循环中对xmlStreamReader.next进行一些迭代。 结果是我们有3个输出文件每个输出文件都符合原始架构每个文件都有2个数据元素 要将大约30GB的XML我在说我的原始工作分配XML具有更复杂的结构而不是此处使用的演示XSD拆分为大约500MB的部分并花费了大约25分钟的时间。 为了测试内存使用率我特意将Xmx设置为32MB。 从图中可以看出内存消耗非常低并且没有GV开销 生活是美好的但并非完全如此。 在那儿我发现有些尴尬的事情需要小心。 在我的实际场景中输入XML没有与之关联的名称空间我很确定它永远不会。 这就是我坚持使用此解决方案的原因。 在演示中这里只有一个名称空间并且已经开始使设置更加脆弱。 问题不在于StAX使用StAX处理名称空间非常简单。 您可以决定具有一个与该模式的目标名称空间相对应的默认名称空间假设您的模式为elementFormDefault qualified并可以为该模式中导入的其他名称空间声明一些带前缀的名称空间。 当XSLT开始干扰输出流时问题就开始出现您可能已经注意到了。 显然它不会检查已经定义了哪些名称空间或发生其他事情。 结果是它们通过使用其他前缀重新定义现有名称空间或重置默认名称空间和其他不需要的内容使文档严重混乱。 如果您需要比默认模板更多的名称空间操作则可能需要XSL。 如果输入文档使用默认名称空间则XSLT也会触发异常。 它将尝试注册名称为“ xmlns”的前缀。 不允许这样做因为xmlns保留用于指示默认名称空间不能用作前缀。 我为此测试申请的解决方案是忽略任何前缀“ xmlns”并忽略与xmlns前缀组合的目标名称空间的添加这就是为什么要使用避免DefaultNsPrefixStreamWriterWrapper。 前缀和名称空间都需要在PreventDefaultNsPrefixStreamWriterWrapper中进行匹配因为如果您要使用的输入文档中没有默认名称空间而是带有前缀例如bigxmlBigXmlTest xmlnsbigxml “ http//…。” bigxmlHeader …。那么您就不能忽略添加名称空间该组合将成为带有“ bigxml”前缀的目标名称空间因为这只会产生数据元素的前缀而没有名称空间绑定例如 ?xml version1.0 encodingUTF-8? BigXmlTest xmlnshttp://www.error.be/bigxmltestHeaderSomeHeaderElementSomething something darkside/SomeHeaderElement/HeaderContentbigxml:DataData1/bigxml:Databigxml:DataData2/bigxml:Data/Content /BigXmlTest 请记住XML的生产者可以自由选择还是在elementFormDefault 合格的情况下选择使用默认命名空间还是为每个元素添加前缀。 该代码应该透明地能够处理这两种情况。 为方便起见请使用PreventDefaultNsPrefixStreamWriterWrapper代码 public class AvoidDefaultNsPrefixStreamWriterWrapper extends XMLStreamWriterAdapter { ...Overridepublic void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {if (defaultNs.equals(namespaceURI) xmlns.equals(prefix)) {return;}super.writeNamespace(prefix, namespaceURI);}Overridepublic void setPrefix(String prefix, String uri) throws XMLStreamException {if (prefix.equals(xmlns)) {return;}super.setPrefix(prefix, uri);} 最后我还写了一个版本点击 此处完全适用于GitHub但这次使用的是StAX迭代器API。 您会注意到不再需要繁琐的XSLT来流传输到输出。 只需将每个感兴趣的事件添加到输出中即可。 通过首先使用游标API验证输入然后使用Iterator API解析输入可以解决缺少验证的问题。 这将花费更长的时间但是在大多数情况下仍然可以接受。 最重要的是 while (xmlEventReader.hasNext()) {XMLEvent event xmlEventReader.nextEvent();if (event.isStartElement() event.asStartElement().getName().getLocalPart().equals(CONTENT_ELEMENT)) {event xmlEventReader.nextEvent();while (!(event.isEndElement() event.asEndElement().getName().getLocalPart().equals(CONTENT_ELEMENT))) {if (dataRepetitions ! 0 event.isStartElement() event.asStartElement().getName().getLocalPart().equals(DATA_ELEMENT) dataRepetitions % 2 0) { // %2 just for testing: replace this by for example checking the actual size of the current// output filexmlEventWriter.close(); // Also closes any open Element(s) and the documentxmlEventWriter openOutputFileAndWriteHeader(fileNumber); // Continue with next filedataRepetitions 0;}// Write the current event to outputxmlEventWriter.add(event);event xmlEventReader.nextEvent();if (event.isEndElement() event.asEndElement().getName().getLocalPart().equals(DATA_ELEMENT)) {dataRepetitions;}}}} 在第2行您将看到返回XMLEvent其中包含有关当前节点的所有信息。 在第4行上您看到使用此表单检查元素类型更容易与其与常量进行比较还可以使用对象模型。 在第19行要将元素从输入复制到输出我们只需将Event添加到XMLEventWriter。 参考来自Koen Serneels –技术博客博客的JCG合作伙伴 Koen Serneels 分离Java中的大型XML文件 。 翻译自: https://www.javacodegeeks.com/2013/08/splitting-large-xml-files-in-java.html
http://www.zqtcl.cn/news/548903/

相关文章:

  • 关于实验室建设的英文网站深圳企业网站制作公司怎样
  • wordpress全站背景音乐中山网站搜索排名
  • 搭建网站的过程透明主题wordpress
  • 丰台网站建设公司电话深圳微信商城网站设计公司
  • 做淘宝要用的网站吗上海微信网站
  • 佛山高端网站制作公司wordpress 发送邮件插件
  • 类似站酷的设计类网站网站建设需要待摊吗
  • 用php做视频网站在学做网站还不知道买什么好
  • wordpress培训类网站网站建设 好
  • 网站开发需要2个月吗网站建设案例精粹
  • 网站建设项目职责营销型网站建设五大内容
  • 建设工程监理招标网站W做网站
  • 网站建设与维护教学课件网站上线前做环境部署
  • 信誉好的网站建设做网站成为首富的外国人
  • 常州网站制作市场湖北省荆门市城乡建设网站
  • 泉州网站制作运营商专业北京软件公司招聘信息查询
  • 车床加工东莞网站建设网站建设教学改进
  • 深圳专业做网站建设西安网站建设有限公司
  • wordpress 一键建站wordpress子主题style
  • 昆明设计网站怎么做网络广告
  • 2018什么做网站深圳企业网站设
  • 北京旅游外贸网站建设博客集成wordpress
  • 中国最好的建设网站哪些网站教你做系统
  • 自己做网站别人怎么看见网站建设办公
  • 凡科做网站视频网站哪家好
  • 查询网站是否正规营销策略国内外文献综述
  • 做网页用的网站wordpress用户角色权限管理
  • 怎么查网站备案的公司wordpress 无刷新评论
  • 学前心理学课程建设网站百度极速版下载
  • 佛山做营销型网站建设深圳宝安区租房