【问题标题】:XML element with attribute and content using JAXB使用 JAXB 的具有属性和内容的 XML 元素
【发布时间】:2011-07-27 18:00:43
【问题描述】:

如何使用 JAXB 生成以下 XML?

<sport type="" gender="">
    sport description
</sport>

【问题讨论】:

    标签: java xml jaxb


    【解决方案1】:

    @XmlAttribute注释类型和性别属性,用@XmlValue注释描述属性:

    package org.example.sport;
    
    import javax.xml.bind.annotation.*;
    
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlRootElement
    public class Sport {
    
        @XmlAttribute
        protected String type;
    
        @XmlAttribute
        protected String gender;
    
        @XmlValue;
        protected String description;
    
    }
    

    更多信息

    【讨论】:

      【解决方案2】:

      正确的方案应该是:

      <?xml version="1.0" encoding="UTF-8"?>
      <schema xmlns="http://www.w3.org/2001/XMLSchema" 
      targetNamespace="http://www.example.org/Sport"
      xmlns:tns="http://www.example.org/Sport" 
      elementFormDefault="qualified"
      xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
      jaxb:version="2.0">
      
      <complexType name="sportType">
          <simpleContent>
              <extension base="string">
                  <attribute name="type" type="string" />
                  <attribute name="gender" type="string" />
              </extension>
          </simpleContent>
      </complexType>
      
      <element name="sports">
          <complexType>
              <sequence>
                  <element name="sport" minOccurs="0" maxOccurs="unbounded"
                      type="tns:sportType" />
              </sequence>
          </complexType>
      </element>
      

      为 SportType 生成的代码将是:

      package org.example.sport;
      
      import javax.xml.bind.annotation.XmlAccessType;
      import javax.xml.bind.annotation.XmlAccessorType;
      import javax.xml.bind.annotation.XmlAttribute;
      import javax.xml.bind.annotation.XmlType;
      
      
      @XmlAccessorType(XmlAccessType.FIELD)
      @XmlType(name = "sportType")
      public class SportType {
          @XmlValue
          protected String value;
          @XmlAttribute
          protected String type;
          @XmlAttribute
          protected String gender;
      
          public String getValue() {
              return value;
          }
      
          public void setValue(String value) {
              this.value = value;
          }
      
          public String getType() {
          return type;
          }
      
      
          public void setType(String value) {
              this.type = value;
          }
      
          public String getGender() {
              return gender;
          }
      
          public void setGender(String value) {
              this.gender = value;
          }
      }
      

      【讨论】:

        【解决方案3】:

        这是可行的解决方案:

        输出:

        public class XmlTest {
        
            private static final Logger log = LoggerFactory.getLogger(XmlTest.class);
        
            @Test
            public void createDefaultBook() throws JAXBException {
                JAXBContext jaxbContext = JAXBContext.newInstance(Book.class);
                Marshaller marshaller = jaxbContext.createMarshaller();
        
                StringWriter writer = new StringWriter();
                marshaller.marshal(new Book(), writer);
        
                log.debug("Book xml:\n {}", writer.toString());
            }
        
        
            @XmlAccessorType(XmlAccessType.FIELD)
            @XmlRootElement(name = "book")
            public static class Book {
        
                @XmlElementRef(name = "price")
                private Price price = new Price();
        
        
            }
        
            @XmlAccessorType(XmlAccessType.FIELD)
            @XmlRootElement(name = "price")
            public static class Price {
                @XmlAttribute(name = "drawable")
                private Boolean drawable = true; //you may want to set default value here
        
                @XmlValue
                private int priceValue = 1234;
        
                public Boolean getDrawable() {
                    return drawable;
                }
        
                public void setDrawable(Boolean drawable) {
                    this.drawable = drawable;
                }
        
                public int getPriceValue() {
                    return priceValue;
                }
        
                public void setPriceValue(int priceValue) {
                    this.priceValue = priceValue;
                }
            }
        }
        

        输出:

        22:00:18.471 [main] 调试 com.grebski.stack.XmlTest - Book xml:

        <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
        <book>
            <price drawable="true">1234</price>
        </book>
        

        【讨论】:

        • 只是想添加一个类似答案的链接,以帮助那些将其视为解决方案的人。好答案,顺便说一句。 stackoverflow.com/a/15429363/1686575
        • 你救我! :D 我使用@XmlValue 解决了
        【解决方案4】:

        更新的解决方案 - 使用我们正在讨论的架构解决方案。这会让你得到答案:

        示例架构:

        <?xml version="1.0" encoding="UTF-8"?>
        <schema xmlns="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://www.example.org/Sport"
        xmlns:tns="http://www.example.org/Sport" 
        elementFormDefault="qualified"
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
        jaxb:version="2.0">
        
        <complexType name="sportType">
            <attribute name="type" type="string" />
            <attribute name="gender" type="string" />
        </complexType>
        
        <element name="sports">
            <complexType>
                <sequence>
                    <element name="sport" minOccurs="0" maxOccurs="unbounded"
                        type="tns:sportType" />
                </sequence>
            </complexType>
        </element>
        

        生成的代码

        运动类型:

        package org.example.sport; 
        
        import javax.xml.bind.annotation.XmlAccessType;
        import javax.xml.bind.annotation.XmlAccessorType;
        import javax.xml.bind.annotation.XmlAttribute;
        import javax.xml.bind.annotation.XmlType;
        
        
        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "sportType")
        public class SportType {
        
            @XmlAttribute
            protected String type;
            @XmlAttribute
            protected String gender;
        
            public String getType() {
                return type;
            }
        
        
            public void setType(String value) {
                this.type = value;
            }
        
            public String getGender() {
                return gender;
            }
        
            public void setGender(String value) {
                this.gender = value;
            }
        
        }
        

        运动:

        package org.example.sport;
        
        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.XmlRootElement;
        import javax.xml.bind.annotation.XmlType;
        
        
        @XmlAccessorType(XmlAccessType.FIELD)
        @XmlType(name = "", propOrder = {
                "sport"
        })
        @XmlRootElement(name = "sports")
        public class Sports {
        
            protected List<SportType> sport;
        
            public List<SportType> getSport() {
                if (sport == null) {
                    sport = new ArrayList<SportType>();
                }
                return this.sport;
            }
        
        }
        

        通过在命令行上针对模式运行 xjc 来生成输出类文件

        【讨论】:

        • 不使用 XSD。使用 JAXB 注释。
        • 当然可以,但是您可以生成一个非常简单的 XSD 来描述上述 XML 结构,从而为您生成带有注释的 Java 代码文件。或者,您可以手动构建它们,注释结构应该在文档中。使用 XSD 的优点是可以非常快速地更改结构并重新生成 java 代码文件。这取决于你对这两种方法的舒适程度download.oracle.com/javaee/5/tutorial/doc/bnbah.html
        • 感谢您的回复。但我的问题是如何手动使用注释生成给定的 XML。我需要如何定义我的实体类文件?
        • 在上面看到我的新解决方案,真的希望这会有所帮助
        猜你喜欢
        • 2013-01-10
        • 1970-01-01
        • 2016-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多