2011-07-05 85 views
9

IM在一個Java項目,我需要從一個XML文件中讀取一些對象,做一些處理,這將改變object's atributes然後寫對象到另一個XML文件的工作。爲此,我使用JAXB以其編組和解組的能力,他們每個人的方法,像這樣:JAXB XML對象沒有命名空間前綴編組

private MyObject unmarshallXMLFile(String file) { 
    MyObject t=null; 
    try { 
     jc = JAXBContext.newInstance("foo.bar"); 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     SchemaFactory sf = SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI); 
     unmarshaller.setSchema(sf.newSchema(new File("MySchema.xsd"))); 
     t = (Task) unmarshaller.unmarshal(new File(file)); 
    } catch (JAXBException e) { 
     e.printStackTrace(); 
    } catch (SAXException e) { 
     e.printStackTrace(); 
    } 
    return t; 
} 

private void marshallXMLFile(String file) { 
    task.setReplay(Boolean.TRUE); 
    Marshaller marshaller; 
    try { 
     marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true)); 
     marshaller.marshal(task, new FileOutputStream(file)); 
    } catch (JAXBException e) { 
     e.printStackTrace(); 
    } catch (FileNotFoundException e) { 
     e.printStackTrace(); 
    } 

} 

的問題是自動生成的命名空間前綴,如NS2或NS3不斷出現在輸出文件,然後當我想重用與unmarshallXMLFile方法這個文件(我會再次使用該輸出文件作爲輸入以後)就不會得到有效的對抗模式,並拋出一個org.xml.sax.SAXParseException。下面是我寫的文件:

XML模式:MySchema.xsd

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/MySchema" 
    xmlns:spm="http://www.example.org/MySchema" 
    elementFormDefault="qualified" 
    attributeFormDefault="qualified"> 

    <element name="task" > 
     <complexType> 
      <sequence> 
       <element name="replay" type="boolean" default="false"/> 
       <element name="threads" type="spm:spThread" maxOccurs="unbounded" minOccurs="1" /> 
      </sequence> 
     </complexType> 
    </element> 

    <complexType name="spThread"> 
     <sequence> 
      <element name="SPThreadID" type="int" /> 
      <element name="durtime" minOccurs="0" default="0"> 
       <simpleType> 
        <restriction base="int"> 
         <minInclusive value="0" /> 
        </restriction> 
       </simpleType> 
      </element> 
      <element name="minexecutions" minOccurs="0" default="0"> 
       <simpleType> 
        <restriction base="int"> 
         <minInclusive value="0" /> 
        </restriction> 
       </simpleType> 
      </element> 
      <element name="numThreads" type="int" /> 
      <element name="procedures" type="spm:procedure" minOccurs="1" 
       maxOccurs="unbounded" /> 
     </sequence> 
    </complexType> 

    <complexType name="procedure"> 
     <sequence> 
      <element name="id" type="int" minOccurs="1" /> 
      <element name="name" type="string" minOccurs="1" /> 
      <element name="weight" minOccurs="1"> 
       <simpleType> 
        <restriction base="int"> 
         <minInclusive value="0" /> 
         <maxInclusive value="100" /> 
        </restriction> 
       </simpleType> 
      </element> 
      <element name="parameterPool" type="spm:parameter" nillable="true" 
       minOccurs="0" maxOccurs="unbounded" /> 
     </sequence> 
    </complexType> 

    <complexType name="parameter"> 
     <sequence> 
      <element name="name" type="string" minOccurs="1" /> 
      <element name="dataType" type="spm:parameterDataType" default="integer"/> 
      <element name="parmType" type="spm:parameterType" default="in" 
       minOccurs="0" /> 
      <element name="minValue" type="string"/> 
      <element name="maxValue" type="string"/> 
      <element name="value" type="string"/> 
     </sequence> 
    </complexType> 

    <simpleType name="parameterDataType"> 
     <restriction base="string"> 
      <enumeration value="integer" /> 
      <enumeration value="varchar" /> 
      <enumeration value="char" /> 
     </restriction> 
    </simpleType> 

    <simpleType name="parameterType"> 
     <restriction base="string"> 
      <enumeration value="in" /> 
      <enumeration value="out" /> 
      <enumeration value="in_out" /> 
     </restriction> 
    </simpleType> 

</schema> 

輸入文件:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<task xmlns="http://www.example.org/MySchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/MySchema MySchema.xsd "> 
    <replay>true</replay> 
    <threads> 
     <SPThreadID>0</SPThreadID> 
     <durtime>10</durtime> 
     <minexecutions>2</minexecutions> 
     <numThreads>3</numThreads> 
     <procedures> 
      <id>1</id> 
      <name>run</name> 
      <weight>15</weight> 
      <parameterPool> 
       <name>energy</name> 
       <dataType>integer</dataType> 
       <parmType>in</parmType> 
       <minValue>10</minValue> 
       <maxValue>50</maxValue> 
       <value>11</value>     
      </parameterPool> 
      <parameterPool> 
       <name>speed</name> 
       <dataType>integer</dataType> 
       <parmType>in</parmType> 
       <minValue>12</minValue> 
       <maxValue>80</maxValue> 
       <value>13</value>         
      </parameterPool> 
     </procedures> 
    </threads> 
</task> 

輸出文件(不加任何處理責任:剛剛解組,並與方法編組回前面提到)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<ns2:task xmlns="http://www.example.org/MySchema" xmlns:ns2="http://www.example.org/MySchema.xsd"> 
    <replay>true</replay> 
    <threads> 
     <SPThreadID>0</SPThreadID> 
     <durtime>10</durtime> 
     <minexecutions>2</minexecutions> 
     <numThreads>3</numThreads> 
     <procedures> 
      <id>1</id> 
      <name>run</name> 
      <weight>15</weight> 
      <parameterPool> 
       <name>energy</name> 
       <dataType>integer</dataType> 
       <parmType>in</parmType> 
       <minValue>10</minValue> 
       <maxValue>50</maxValue> 
       <value>11</value> 
      </parameterPool> 
      <parameterPool> 
       <name>speed</name> 
       <dataType>integer</dataType> 
       <parmType>in</parmType> 
       <minValue>12</minValue> 
       <maxValue>80</maxValue> 
       <value>13</value> 
      </parameterPool> 
     </procedures> 
    </threads> 
</ns2:task> 

異常(當再次使用輸出文件時S上輸入):

javax.xml.bind.UnmarshalException 
- with linked exception: 
[org.xml.sax.SAXParseException: cvc-elt.1: The declaration of the element'ns3:task' could not be found.] 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:326) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:500) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:206) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:175) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:148) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:153) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162) 
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:180) 
    at Test.main(Test.java:48) 
Caused by: org.xml.sax.SAXParseException: cvc-elt.1: The declaration of the element'ns3:task' could not be found. 
    at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source) 
    at org.apache.xerces.util.ErrorHandlerWrapper.error(Unknown Source) 
    at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source) 
    at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source) 
    at org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source) 
    at org.apache.xerces.impl.xs.XMLSchemaValidator.startElement(Unknown Source) 
    at org.apache.xerces.jaxp.validation.XMLSchemaValidatorHandler.startElement(Unknown Source) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.startElement(ValidatingUnmarshaller.java:85) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:113) 
    at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source) 
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source) 
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl$NSContentDispatcher.scanRootElementHook(Unknown Source) 
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source) 
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) 
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) 
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) 
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) 
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source) 
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:202) 
    ... 6 more 

從來就一直唸叨的主題,並試圖解答相關的負荷,但他們都不似乎去掉前綴。我走到低谷這個guide但JAXB我使用不支持NamespacePrefixMapper的版本。我嘗試使用註釋here來配置前綴,但不起作用。

也許有一種擺脫這個命名空間前綴的方法:我找到的所有論壇,答案和討論都是關於自定義這個前綴的,我只是想擺脫它們。但不知怎的,它讓我覺得我在輸入文件和模式中都缺少一些東西。他們寫得好嗎?我要說的是那裏的問題,因爲這是我第一次在這個深度與XML和XSD工作,什麼從來就做了只基於什麼從來就在網上找到。有關改進xml和xsd設計的任何提示將不勝感激

我應該在輸入文件中還是在架構中使用某種前綴,以便JAXB框架在編組時不會生成隨機前綴?

在此先感謝,我希望你們能幫助我。

-

非常感謝您的回答。這樣我就可以使用NamespacePrefixMapper。然而,當我使用它,我的代碼不斷拋出異常,當我運行它:

Exception in thread "main" java.util.MissingResourceException: Can't find bundle for base name javax.xml.bind.Messages, locale de_DE 
    at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:863) 
    at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:832) 
    at java.util.ResourceBundle.getBundle(ResourceBundle.java:576) 
    at javax.xml.bind.Messages.format(Messages.java:47) 
    at javax.xml.bind.Messages.format(Messages.java:36) 
    at javax.xml.bind.PropertyException.<init>(PropertyException.java:99) 
    at javax.xml.bind.helpers.AbstractMarshallerImpl.setProperty(AbstractMarshallerImpl.java:349) 
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.setProperty(MarshallerImpl.java:527) 
    at Test.main(Test.java:95) 

我發現它有做一些與屬性文件:我不使用這樣的事情,我還沒有改變任何東西。

+0

相似主題/可能重複:http://stackoverflow.com/questions/1982977/is-it-possible-to-custo mize-the-namespace-prefix-that-jaxb -chain-marshalling –

回答

3

好了,經過一番研究,我嘗試使用的類我試圖序列的每個屬性的@XMLElement標籤,清楚說明什麼我的名字空間中,並使用同一個屬性上:

@XmlElement(required = true, name="myObjectPool", namespace="http://www.example.org/StoredProceduresSchema") 
    protected List<MyObject> myObjectPool; 

它的工作完美無缺:編組文件中沒有更多奇怪的命名空間。

我想感謝他的回答:我也嘗試過,但我有一個奇怪的語言包相關的異常。我很高興這個更簡單的方法解決了這個問題。

+0

我們可以在@XmlElement中使用前綴 –

3

嘗試使用NamespacePrefixMapper

NamespacePrefixMapper mapper = new NamespacePrefixMapper() { 
    public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) { 
     return ""; 
    } 
}; 
marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", mapper); 
+0

非常感謝您的回答。這樣我就可以使用NamespacePrefixMapper。但是,當我使用它時,我的代碼在運行時會一直拋出異常: – Lak

11

而不是在每個元素中指定@XmlElement的名稱空間屬性,而是在包級別註釋更簡單。 你可以通過在你想註解的包的下面創建一個文件package-info.java來達到這個目的。

例如,如果你想註釋包org.example,然後一個名爲package-info.java文件必須放在目錄組織/例子中,內容如下:

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.org/StoredProceduresSchema", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) 
package org.example; 

需要注意的是,你必須註解是很重要的每個包含您計劃編組或被這些人引用的類的包。

希望這有助於:)

1

Java的解決方案7/8

此問題與默認實現JAXB提供程序有關。我找到了一個使用不同實現的解決方案:EclipseLink MOXy

1.添加的依賴性在 pom.xml
<dependency> 
    <groupId>org.eclipse.persistence</groupId> 
    <artifactId>org.eclipse.persistence.moxy</artifactId> 
    <version>2.5.0</version> 
</dependency>` 
2.創建包含以下行
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

動議文件到封裝模型

3.創建包文件的文件jaxb.properties。 java進入模型包
@XmlSchema(xmlns = { @XmlNs(prefix = "video", namespaceURI = "http://www.google.com/schemas/sitemap-video/1.1"), 
     @XmlNs(prefix = "", namespaceURI = "http://www.sitemaps.org/schemas/sitemap/0.9")}) 

package it.my.sitemap.model; 

import javax.xml.bind.annotation.XmlNs; 
import javax.xml.bind.annotation.XmlSchema; 
相關問題