JAXB 中的解组器和架构

2024-01-09

我有可以以各种格式保存文件的应用程序(所有格式都是xml)。所以我应该解决确定文件保存格式的问题。所以,我看到了 2 个解决方案

  • 不同的格式有不同的模式,所以我可以通过它们来确定它。 我以我得到的方式设置模式here https://stackoverflow.com/questions/4473430/jaxb-marshaller-with-specified-schema

marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "bla-bla.xsd");

所以我想我可以使用它unmarshaller.getProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION)

但它扔

javax.xml.bind.PropertyException: jaxb.noNamespaceSchemaLocation

and getSchema()返回空值 所以,如何获取架构位置?

  • 使用以下命令为不同的 bean 指定不同的适配器setAdapter(Class<A> type, A adapter) method

什么方式比较好?如果首先,那么如何获取架构位置标签?

upd 代码示例假设我们有豆子

@XmlRootElement
public class Foo{
    String bar;
    public String getBar() {return bar; }
    public void setBar(String bar) {this.bar = bar;}
}

以及生成模式、保存 Foo 实例并然后加载的代码。

public class Test {
    final static String schemaLoc = "fooschema.xsd";


    public static void write(File file, Foo foo, Schema schema) throws Throwable {
        XMLEventWriter xsw = null;
        try{
            JAXBContext context = JAXBContext.newInstance(Foo.class);
            XMLOutputFactory xof = XMLOutputFactory.newInstance();
            OutputStream out = new FileOutputStream(file);
            xsw = xof.createXMLEventWriter(out);
            Marshaller m = context.createMarshaller();
            m.setSchema(schema);    //schema setted
            System.out.println(">>>marchal : " + m.getSchema());    //check it
            m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            m.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, schemaLoc);
            m.marshal(foo, xsw);
        } finally{
             xsw.close();
        }
    }

    public static Foo load(File file) throws Throwable {
        JAXBContext context = JAXBContext.newInstance(Foo.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();


        System.out.println("unmarshaller schema:" + unmarshaller.getSchema());  //I need get it here
    //  System.out.println("schema_prop:" + unmarshaller.getProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION));

        InputStreamReader in = new InputStreamReader(new FileInputStream(file));
        XMLEventReader xer = XMLInputFactory.newInstance()
                .createXMLEventReader(in);
        return Foo.class.cast(unmarshaller.unmarshal(xer));
    }

    private static File createSchema(String schemaLocation) throws Throwable{
        final File target = new File(schemaLocation);
        if(!target.exists()){
            JAXBContext jaxbContext = JAXBContext.newInstance(Foo.class);
            SchemaOutputResolver sor = new SchemaOutputResolver() {
                public Result createOutput(String namespaceURI, String suggestedFileName)
                throws IOException {
                    StreamResult result = new StreamResult(target);
                    result.setSystemId(target.toURI().toURL().toString());
                    return result;
                }
            };
            jaxbContext.generateSchema(sor);
        }
        return target;
    }

    public static void main(String[] args) throws Throwable {
        createSchema(schemaLoc);
        File file = new File("temp.xml");
        Foo foo = new Foo();
        foo.setBar("test bar");
        SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
        Schema schema = factory.newSchema(createSchema(schemaLoc));
        write(file, foo, schema);
        System.out.println("result " + load(file).getBar());
    }

}

生成的模式

      <xs:element name="foo" type="foo"/>

      <xs:complexType name="foo">
        <xs:sequence>
          <xs:element name="bar" type="xs:string" minOccurs="0"/>
        </xs:sequence>
      </xs:complexType>
    </xs:schema>

我们的临时文件

<?xml version="1.0"?>
<foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="fooschema.xsd">
<bar>test bar</bar></foo>

正如我们所见,有

xsi:noNamespaceSchemaLocation="fooschema.xsd"

如何使用 JAXB 获取此文本?


我将利用 StAX 解析器来获取此信息(参见下面的示例)。在输入上创建 XMLStreamReader。使用以下命令将 XMLStreamReader 前进到根元素下一个标签()方法。然后获取根元素的 noNamespaceSchemaLocation 属性。然后将 XMLStreamReader 传递给解组(XMLStreamReader)Unmarshaller 上的方法。

import java.io.FileInputStream;
import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext context = JAXBContext.newInstance(Categories.class);

        XMLInputFactory xif = XMLInputFactory.newInstance();
        FileInputStream fis = new FileInputStream("input.xml");
        XMLStreamReader xsr = xif.createXMLStreamReader(fis);
        xsr.nextTag();
        String noNamespaceSchemaLocation = xsr.getAttributeValue(XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI, "noNamespaceSchemaLocation");
        System.out.println(noNamespaceSchemaLocation);

        Unmarshaller um = context.createUnmarshaller();
        Categories response = (Categories) um.unmarshal(xsr);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAXB 中的解组器和架构 的相关文章

  • 如何使用 Java Swing 创建图像映射?

    我需要使用 Swing 制作一个显示背景图像的图像地图 然后当鼠标悬停在 或单击 特定热点上时 我需要弹出一个 放大 图像并显示它 我正在考虑扩展 JPanel 以包含图像引用并通过 PaintComponent g 方法绘制该图像 到目前
  • Mockito:使用“thenReturn”中的方法返回模拟不起作用

    我遇到了我认为可能是 Mockito 的错误 但想知道是否有其他人可以解释为什么这个测试不起作用 基本上 我有两个对象 如下所示 public class FirstObject private SecondObject secondObj
  • 将 for 循环转换为 concat String 为 lambda 表达式

    我有以下 for 循环 它迭代字符串列表并将每个单词的第一个字符存储在StringBuilder 我想知道如何将其转换为 lambda 表达式 StringBuilder chars new StringBuilder for String
  • 读取时 R 中的内存错误.xlsx

    我正在使用以下 R 代码 也利用 Java 参数来增加内存 library xlsx options java parameters Xmx1g library XLConnect NiVe lt read xlsx version1 xl
  • 如何在 Spring Data MongoDB 中仅返回查询的特定字段?

    我们如何在 Spring Data Mongo 中选择特定字段 我尝试了以下操作 但我得到了强制转换异常Foo to String Using Query Query value path 0 fields path 0 String fi
  • 从java管理unix进程的最佳方法是什么?

    我正在寻找一些简单的任务 例如列出用户的所有正在运行的进程 或者通过pid等杀死特定进程 来自Java的基本unix进程管理 有没有相对成熟且有文档的库 我可以从 JVM 运行外部命令 然后解析标准输出 错误 但这似乎需要大量工作 而且一点
  • 为什么java.util.Collection不直接定义next()、hasNext()呢?

    If 收藏定义有下一个 代替迭代器 hasNext 我们可以更容易地编写循环 while collection hasNext 代替 Iterator it collection iterator While it hasNext 当然 我
  • 在准备好的语句中使用“like”通配符

    我正在使用准备好的语句来执行 mysql 数据库查询 我想实现基于某种关键字的搜索功能 为此我需要使用LIKE关键字 我知道的就这么多 我以前也使用过准备好的语句 但我不知道如何使用它LIKE因为从下面的代码中我将在哪里添加 keyword
  • JOOQ初始化DAO最佳方法

    我想知道初始化 JOOQ 生成 DAO 的最佳实践 现在 我使用以下方法来初始化 JOOQ 生成的 DAO 在以下情况下 Student Dao 是 JOOQ 生成的 public class ExtendedStudentDAO exte
  • java中应用程序的CPU核心数和线程数之间有什么关系?

    我是java新手多线程编程 我想到的问题是 根据我的数量 我可以运行多少个线程CPU核心数 如果我运行的线程超过CPU核心数机器运行应用程序会产生开销吗 例如 当我们有一台服务器计算机 其中有一个运行 2 个线程 主线程 开发人员线程 的服
  • JTable 使用行号?

    我正在创建一个程序 其工作原理如下Microsoft Excel 在JAVA中 我的问题是如何将行号放在每行旁边JTable 我已经看到它在其他 Java 程序中工作 我只是不知道如何将它包含在我的程序中 谷歌给了我这个网站 http ti
  • 如何设置鼠标监听器的优先级

    我有一个带有列表和按钮的面板 名单已定MouseAdapter with mouseClick 我添加到面板MouseAdapter with mousePressed and mouseReleased and MouseMotionAd
  • Java错误:不是一个语句,我不知道为什么?

    我真的不确定是什么导致发生这个编译时错误 我一直在试图弄清楚 但似乎找不到问题所在 ClassTable java 253 error not a statement class c class classes nextElement Cl
  • org.openqa.selenium.remote.service.DriverService$Builder.createArgs()Lcom/google/common/collect/ImmutableList;使用 Selenium 3.5.3

    我正在使用 IntelliJ 编写 Selenium Junit 测试 如果我直接从测试触发 测试运行正常 但是 如果我使用 JunitCore 触发 TestRunnerSuite 的测试 我遇到了以下奇怪的错误 在谷歌研究后我没有找到解
  • Log4j 不打印完整的堆栈跟踪

    我检查了 SO 中的所有答案 但没有一个真正帮助我 我的 Log4j 属性文件 log4j rootLogger debug console file log4j appender console org apache log4j Cons
  • 在 OpenCV 中将 `BufferedImage` 转换为 `Mat`

    我怎样才能转换BufferedImage to a Mat in OpenCV 我正在使用 JAVA 包装器OpenCV not JavaCV 由于我是新手OpenCV我在理解如何做时遇到一些问题Mat works 我想做这样的事情 基于
  • Java 错误:默认构造函数未定义隐式超级构造函数

    我有一些简单的 Java 代码 其结构与此类似 abstract public class BaseClass String someString public BaseClass String someString this someSt
  • JavaFX ComboBox - 显示文本但在选择时返回 ID

    我有一个包含机场的数据库表 每个机场都有一个名称和一个 ID 在 JavaFX 中我有一个表单 其中包含ComboBox 组合框需要显示所有机场名称 并且在提交表单时需要将机场的 ID 插入数据库 而不是其名称 但我并没有真正弄清楚解决方案
  • 可选的比较器

    I have abstract class OptionalComparator
  • 如何更改 Java 中不同类的变量?

    如何更改 Java 中不同类的变量 我正在尝试更改另一个类中的变量 然后在第一个类中使用它 我在 First 类中创建了一个变量 并将其值设置为 1 然后我尝试在 Second 类中将同一变量的值更改为 2 但是当我在 First 类中使用

随机推荐