当前位置: 首页 > 工具软件 > Saxon > 使用案例 >

saxon 使用_Java XML和JSON:Java SE的文档处理,第1部分:SAXON和Jackson

东郭元魁
2023-12-01

saxon 使用

XML和JSON对我来说很重要,我感谢Apress让我写了一整本有关它们的书。 在本文中,我将简要介绍新书的第二版Java XML和JSON 。 如果有足够的空间,我还将展示两个有用的演示,希望将它们包含在书中。

首先,我将向您展示如何使用XSLT 2.0+和XPath 2.0+兼容的替代品(在本例中为SAXON)重写Xalan,这是Java 11的标准XSLT实现。 使用SAXON for XSLT / XPath可以更轻松地访问诸如分组之类的功能,我还将对此进行演示。 接下来,我将向您展示两种使用Jackson转换XML到JSON的方法:第一种技术是数据绑定,第二种是树遍历。

获取代码

下载本教程中示例的源代码

为什么使用XML和JSON?

在XML到来之前,我编写了软件来导入以未记录的二进制格式存储的数据。 我使用调试器来识别数据字段类型,文件偏移量和长度。 当出现XML和JSON时,这项技术极大地简化了我的生活。

Java XML和JSON的第一版(2016年6月)介绍了XML和JSON,探讨了Java SE自己的面向XML的API,并探讨了Java SE的外部面向JSON的API。 由Apress最近发行的第二版提供了新内容,并(希望)回答了有关XML,JSON,Java SE的XML API和各种JSON API(包括JSON-P)的更多问题。 它还针对Java SE 11更新。

写完这本书之后,我写了另外两个部分,分别介绍了SAXON和Jackson的有用功能。 我将在本文中介绍这些部分。 首先,我将花一点时间介绍这本书及其内容。

Java XML和JSON,第二版

理想情况下,在研究本文的其他内容之前,您应该阅读Java XML和JSON的第二版。 即使您还没有读过这本书,也应该知道本书的内容,因为该信息将其他内容放在上下文中。

Java XML和JSON的第二版分为三个部分,包括12章和附录:

  • 第1部分:探索XML
    • 第1章:XML简介
    • 第2章:使用SAX解析XML文档
    • 第3章:使用DOM解析和创建XML文档
    • 第4章:使用StAX解析和创建XML文档
    • 第5章:使用XPath选择节点
    • 第6章:使用XSLT转换XML文档
  • 第2部分:探索JSON
    • 第7章:JSON简介
    • 第8章:使用mJson解析和创建JSON对象
    • 第9章:使用Gson解析和创建JSON对象
    • 第10章:使用JsonPath提取JSON值
    • 第11章:使用Jackson处理JSON
    • 第12章:使用JSON-P处理JSON
  • 第3部分:附录
    • 附录A:练习答案

第1部分重点介绍XML。 第1章定义了关键术语,介绍了XML语言功能(XML声明,元素和属性,字符引用和CDATA部分,名称空间以及注释和处理指令),并介绍了XML文档验证(通过文档类型定义和模式)。 其余五章探讨Java SE的SAX,DOM,StAX,XPath和XSLT API。

第2部分重点介绍JSON。 第7章定义关键术语,介绍JSON语法,在JavaScript上下文中演示JSON(因为Java SE尚未正式支持JSON),并演示了如何验证JSON对象(通过JSON Schema Validator在线工具)。 其余五章探讨了第三方mJSon,Gson,JsonPath和Jackson API。 以及Oracle面向Java EE的JSON-P API,该API也可以非正式地用于Java SE上下文中。

每章都以一组练习(包括编程练习)结尾,这些练习旨在增强读者对材料的理解。 答案在本书的附录中显示。

新版本在某些方面与先前版本有所不同:

  • 第2章介绍了获取XML阅读器的正确方法。 不建议使用上一版的方法。
  • 第3章还介绍了DOM的Load and Save,Range和Traversal API。
  • 第6章显示了如何使用SAXON超越XSLT / XPath 1.0。
  • 第11章是探讨杰克逊的新篇章(冗长)。
  • 第12章是新的(冗长的)一章,探讨JSON-P。

此版本还纠正了上一版本内容中的细微错误,更新了各种数字,并增加了许多新的练习。

虽然在第二版中没有足够的空间,但将来的Java XML和JSON版本可能会涵盖YAML

XML与JSON? 没那么快。

XML和JSON通常会进行比较,但是它们实际上是相辅相成的。 卢卡斯·沃格尔(Lucas Vogel)在他的文章中指出了这一点JSON与XML:争夺格式霸权之争可能是浪费精力 。”

第6章的附录:使用XSLT转换XML文档

使用SAXON超越XSLT / XPath 1.0

Java 11的XSLT实现基于Apache Xalan Project ,该项目支持XSLT 1.0和XPath 1.0,但仅限于这些早期版本。 要访问更高版本的XSLT 2.0+和XPath 2.0+功能,您需要使用诸如SAXON之类的替代方法来覆盖Xalan实现。

Java XML和JSON,第6章显示了如何使用SAXON覆盖Xalan,然后验证是否正在使用SAXON。 在演示中,我建议在应用程序的main()方法的开头插入以下行,以便使用SAXON:

System.setProperty("javax.xml.transform.TransformerFactory",
                   "net.sf.saxon.TransformerFactoryImpl");

实际上,您不需要此方法调用,因为SAXON的TransformerFactory实现作为一种服务提供在JAR文件中,当可通过类路径访问JAR文件时,该服务会自动加载。 但是,如果类路径上有多个TransformerFactory实现JAR文件,并且Java运行时选择了非SAXON服务作为转换器实现,则可能会出现问题。 包括上述方法调用将使用SAXON覆盖该选择。

XSLT / XPath功能:一个演示

第6章介绍了两个XSLTDemo应用程序,书的代码档案中提供了第三个应用程序。 下面的清单1展示了第四个XSLTDemo演示应用程序,该应用程序重点介绍了XSLT / XPath功能。

清单1. XSLTDemo.java

import java.io.FileReader;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.FactoryConfigurationError;
import javax.xml.parsers.ParserConfigurationException;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;

import javax.xml.transform.dom.DOMSource;

import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.w3c.dom.Document;

import org.xml.sax.SAXException;

import static java.lang.System.*;

public class XSLTDemo
{
   public static void main(String[] args)
   {
      if (args.length != 2)
      {
         err.println("usage: java XSLTDemo xmlfile xslfile");
         return;
      }

      try
      {
         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
         DocumentBuilder db = dbf.newDocumentBuilder();
         Document doc = db.parse(args[0]);
         TransformerFactory tf = TransformerFactory.newInstance();
         out.printf("TransformerFactory: %s%n", tf);
         FileReader fr = new FileReader(args[1]);
         StreamSource ssStyleSheet = new StreamSource(fr);
         Transformer t = tf.newTransformer(ssStyleSheet);
         Source source = new DOMSource(doc);
         Result result = new StreamResult(out);
         t.transform(source, result);
      }
      catch (IOException ioe)
      {
         err.printf("IOE: %s%n", ioe.toString());
      }
      catch (FactoryConfigurationError fce)
      {
         err.printf("FCE: %s%n", fce.toString());
      }
      catch (ParserConfigurationException pce)
      {
         err.printf("PCE: %s%n", pce.toString());
      }
      catch (SAXException saxe)
      {
         err.printf("SAXE: %s%n", saxe.toString());
      }
      catch (TransformerConfigurationException tce)
      {
         err.printf("TCE: %s%n", tce.toString());
      }
      catch (TransformerException te)
      {
         err.printf("TE: %s%n", te.toString());
      }
      catch (TransformerFactoryConfigurationError tfce)
      {
         err.printf("TFCE: %s%n", tfce.toString());
      }
   }
}

清单1中的代码类似于第6章的清单6-2,但是有一些区别。 首先,必须使用两个命令行参数调用清单1的main()方法:第一个参数命名XML文件;第二个参数命名XML文件。 第二个参数命名XSL文件。

第二个区别是我没有在变压器上设置任何输出属性。 具体来说,我没有指定输出方法或是否使用缩进。 这些任务可以在XSL文件中完成。

如下编译清单1:

javac XSLTDemo.java

XSLT 2.0示例:分组节点

XSLT 1.0不提供对分组节点的内置支持。 例如,您可能想要转换以下XML文档,该文档列出了作者的书籍:

<book title="Book 1">
  <author name="Author 1" />
  <author name="Author 2" />
</book>
<book title="Book 2">
  <author name="Author 1" />
</book>
<book title="Book 3">
  <author name="Author 2" />
  <author name="Author 3" />
</book>

到以下XML中,该XML列出了作者及其书籍:

<author name="Author 1">
  <book title="Book 1" />
  <book title="Book 2" />
</author>
<author name="Author 2">
  <book title="Book 1" />
  <book title="Book 3" />
</author>
<author name="Author 3">
  <book title="Book 3" />
</author>

尽管在XSLT 1.0中可以进行这种转换,但是很尴尬。 相比之下,XSLT 2.0的xsl:for-each-group元素使您可以获取一组节点,按某个条件对其进行分组,并处理每个创建的组。

让我们从处理XML文档开始探讨这种功能。 清单2给出了books.xml文件的内容,该文件按书名对作者姓名进行分组。

清单2. books.xml(按书名分组)

<?xml version="1.0"?>
<books>
   <book title="Securing Office 365: Masterminding MDM and Compliance in the Cloud">
     <author name="Matthew Katzer"/>
     <publisher name="Apress" isbn="978-1484242292" pubyear="2019"/>
   </book>
   <book title="Office 2019 For Dummies">
     <author name="Wallace Wang"/>
     <publisher name="For Dummies" isbn="978-1119513988" pubyear="2018"/>
   </book>
   <book title="Office 365: Migrating and Managing Your Business in the Cloud">
     <author name="Matthew Katzer"/>
     <author name="Don Crawford"/>
     <publisher name="Apress" isbn="978-1430265269" pubyear="2014"/>
   </book>
</books>

清单3给出了books.xsl文件的内容,该文件提供了XSL转换,可以将该文档转换为根据作者姓名对书名进行分组的文档。

清单3. books.xsl(按作者姓名分组)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="2.0">
  <xsl:output method="html" indent="yes"/>
  <xsl:template match="/books">
<html>
<head>
</head>
<body>
      <xsl:for-each-group select="book/author" group-by="@name">
      <xsl:sort select="@name"/>
<author name="{@name}">
          <xsl:for-each select="current-group()">
          <xsl:sort select="../@title"/>
<book title="{../@title}" />
          </xsl:for-each>
</author>
      </xsl:for-each-group>
</body>
</html>
  </xsl:template>
</xsl:stylesheet>

xsl:output元素指示需要缩进HTML输出。 xsl:template-match元素与单个books根元素匹配。

xsl:for-each-group元素选择一个节点序列并将其组织为groupsselect属性是一个XPath表达式,用于标识要分组的元素。 在这里,告诉您选择属于book元素的所有author元素。 group-by属性将所有具有相同键值的元素归为一 ,恰好是author元素的@name属性。 从本质上讲,您最终分为以下几组:

Group 1

Matthew Katzer
Matthew Katzer

Group 2

Wallace Wang

Group 3

Don Crawford

这些组不按作者姓名的字母顺序排列,因此将输出author元素,以使Matthew Katzer在前, Don Crawford在后。 xsl:sort select="@name"元素可确保author元素按排序顺序输出。

<author name="{@name}">构造输出一个<author>标记,其name属性仅分配给该组中的第一个作者名称。

继续, xsl:for-each select="current-group()"遍历当前for-each-group迭代组中的作者姓名。 xsl:sort select="../@title"构造将xsl:sort select="../@title"对输出book元素进行排序,该元素通过随后的<book title="{../@title}" />结构指定。

翻译自: https://www.infoworld.com/article/3346229/java-xml-and-json-document-processing-for-java-se-part-1.html

saxon 使用

 类似资料: