jjzjj

java - 如何解码包含 DIFFGR 的 XML 代码

coder 2024-03-17 原文

JAXB 的新手,我正在尝试解码 XML 文档。我使用 xjc 命令从 XSD 文件构建 DataSet 和 ObjectFactory:

<xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="NewDataSet">
    <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
        <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element name="Table">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="AUTHOR" type="xs:string" minOccurs="0"/>
                            <xs:element name="TITLE" type="xs:string" minOccurs="0"/>
                            <xs:element name="ISBN" type="xs:string" minOccurs="0"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:choice>
        </xs:complexType>
    </xs:element>
</xs:schema>

生成的NewDataSet类如下:

package generated;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;


@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "table"
})
@XmlRootElement(name = "NewDataSet")
public class NewDataSet {

    @XmlElement(name = "Table")
    protected List<NewDataSet.Table> table;

    public List<NewDataSet.Table> getTable() {
        if (table == null) {
            table = new ArrayList<NewDataSet.Table>();
        }
        return this.table;
    }


    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "author",
        "title",
        "isbn"
    })
    public static class Table {

        @XmlElement(name = "AUTHOR")
        protected String author;
        @XmlElement(name = "TITLE")
        protected String title;
        @XmlElement(name = "ISBN")
        protected String isbn;

        public String getAUTHOR() {
            return author;
        }

        public void setAUTHOR(String value) {
            this.author = value;
        }

        public String getTITLE() {
            return title;
        }
        public void setTITLE(String value) {
            this.title = value;
        }

        public String getISBN() {
            return isbn;
        }

        public void setISBN(String value) {
            this.isbn = value;
        }

    }

}

ObjectFactory 是:

package generated;

import javax.xml.bind.annotation.XmlRegistry;


@XmlRegistry
public class ObjectFactory {

    public ObjectFactory() {
    }

    public NewDataSet createNewDataSet() {
        return new NewDataSet();
    }

    public NewDataSet.Table createNewDataSetTable() {
        return new NewDataSet.Table();
    }

}

我试图解码的 XML 文件如下:

<NewDataSet xmlns="">
    <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
        <Table diffgr:id="Table1" msdata:rowOrder="0">
            <AUTHOR>Kubo Tite</AUTHOR>
            <TITLE>Bleach</TITLE>
            <ISBN>1234456</ISBN>
        </Table>
        <Table diffgr:id="Table2" msdata:rowOrder="2">
            <AUTHOR>Masashi Kishimoto</AUTHOR>
            <TITLE>Naruto</TITLE>
            <ISBN>435345</ISBN>
        </Table>
        <Table diffgr:id="Table3" msdata:rowOrder="3">
            <AUTHOR>Eiichiro Oda</AUTHOR>
            <TITLE>One Piece</TITLE>
            <ISBN>56767</ISBN>
        </Table>
    </diffgr:diffgram>
</NewDataSet>

执行解码的代码如下:

package consume;

import generated.NewDataSet;
import generated.NewDataSet.Table;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

public class UnmarshallingCode {
    public static void main(String[] args) {
        try{
            File file=new File("data.xml");
            JAXBContext jb=JAXBContext.newInstance(NewDataSet.class);

            Unmarshaller unmarshaller=jb.createUnmarshaller();
            NewDataSet newDataSet=(NewDataSet)unmarshaller.unmarshal(file);
            for(Table t: newDataSet.getTable()){
                System.out.println(t.getTITLE());
            }
        }catch(JAXBException e){
            e.printStackTrace();
        }
    }
}

以上代码不会产生任何错误,但不会产生任何结果。调用 newDataSet.getTable() 返回一个空列表。

但是,如果我从 XML 文件中删除 <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"> 及其相关属性,上面的代码运行良好并在 XML 文档中生成所有标题。但这不是一个允许的解决方案,因为 XML 文档非常大,而且很可能不允许我对结构进行巨大的更改。我怎样才能解码上面提到的 XML 文件?请指教。

最佳答案

您尝试解码的 XML 文档不符合您的 XML 架构。这就是为什么你的 JAXB (JSR-222)实现没有按照您的预期引入数据,以及为什么在您删除 diffgr 元素时引入数据。

移除多余的元素

您可以创建一个过滤的 XMLStreamReader 来删除多余的元素,然后从中解码。

XMLInputFactory xif = XMLInputFactory.newFactory();
StreamSource xml = new StreamSource("src/forum14234091/input.xml");
XMLStreamReader xsr = xif.createXMLStreamReader(xml);

xsr = xif.createFilteredReader(xsr, new StreamFilter() {
    @Override
    public boolean accept(XMLStreamReader xsr) {
        if(xsr.isStartElement() || xsr.isEndElement()) {
            return !"urn:schemas-microsoft-com:xml-diffgram-v1".equals(xsr.getNamespaceURI());
        }
        return true;
    }
});    

创建 JAXBContext

当您从 XML 模式生成 JAXB 模型时,您应该在生成的类的包名而不是根类上创建 JAXBContext。这将确保所有生成的工件都​​得到处理。

JAXBContext jb=JAXBContext.newInstance("generated");

Unmarshaller unmarshaller=jb.createUnmarshaller();
NewDataSet newDataSet=(NewDataSet)unmarshaller.unmarshal(xsr);
for(Table t: newDataSet.getTable()){
    System.out.println(t.getTITLE());
}

更改包名称

默认情况下,生成的类的包名基于targetNamespace,如果没有则generated。您还可以在 XJC 调用期间指定包名称。

xjc -p com.example.foo schema.xsd

关于java - 如何解码包含 DIFFGR 的 XML 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14234091/

有关java - 如何解码包含 DIFFGR 的 XML 代码的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  10. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

随机推荐