2016-11-03 18 views
0

私は、読み込み、編集、およびジャクソンとウッドストックスを使用して(ドキュメントの推奨に従って)書き込むための指示をXMLファイルに渡しました。ほとんどの場合、これはあまりにも難しいことではありません。彼らは、それが何をするかにはかなり良いです。しかし、私は問題に遭遇しました。Jackson/Woodstox XMLエンコードされた文字の解釈

自分のXMLオブジェクト自体にXMLオブジェクトが含まれています。たとえば:

<XMLObject> 
    <OuterObject attributeOne="1" attributeTwo="2" attributeThree="&gt;"> 
     <InnerObject>&lt;NestedObject&gt;Blah&lt;/NestedObject&gt;</InnerObject> 
    </OuterObject> 
    <OuterObject attributeOne="11" attributeTwo="22" attributeThree="&lt;"> 
     <InnerObject>&lt;NestedObject&gt;Blah&lt;/NestedObject&gt;</InnerObject> 
    </OuterObject> 
    <OuterObject attributeOne="111" attributeTwo="222" attributeThree="3" /> 
<XMLObject> 

私はジャクソン・注釈付きJavaオブジェクトにXMLファイルを読み込むとき、&lt;&gt;のそれらのインスタンスのすべては、それぞれ、<>にWoodstoxによって変換されます。私は、XMLファイルとしてバックアウトオブジェクトを作成するときに、<&lt;なるが>は、次のように>

<XMLObject> 
    <OuterObject attributeOne="1" attributeTwo="2" attributeThree=">"> 
     <InnerObject>&lt;NestedObject>Blah&lt;/NestedObject></InnerObject> 
    </OuterObject> 
    <OuterObject attributeOne="11" attributeTwo="22" attributeThree="&lt;"> 
     <InnerObject>&lt;NestedObject>Blah&lt;/NestedObject></InnerObject> 
    </OuterObject> 
    <OuterObject attributeOne="111" attributeTwo="222" attributeThree="3" /> 
<XMLObject> 

ファイルを読むために努力している私の方法の最も簡単なバージョンがあるまま:

@RequestMapping("readXML") 
public @ResponseBody CustomXMLObject readXML() throws Exception { 
    File inputFile = new File(FILE_PATH); 
    XmlMapper mapper = new XmlMapper(); 
    CustomXMLObject value = mapper.readValue(inputFile, CustomXMLObject .class); 

    return value; 
} 

そして、私のジャクソン注釈付きJavaオブジェクトは、私が上に与えた例のようになります:

import com.fasterxml.jackson.annotation.JsonInclude; 
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; 

@JsonInclude(JsonInclude.Include.NON_NULL) 
public class CustomXMLObject { 
    @JacksonXmlProperty(isAttribute=true) 
    private long attributeOne; 
    @JacksonXmlProperty(isAttribute=true) 
    private String attributeTwo; 
    @JacksonXmlProperty(isAttribute=true) 
    private String attributeThree; 
    @JacksonXmlProperty(localName = "InnerObject") 
    private String innerObject; 


    public long getAttributeOne() { 
     return attributeOne; 
    } 

    public void setAttributeOne(long attributeOne) { 
     this.attributeOne = attributeOne; 
    } 

    public String getAttributeTwo() { 
     return attributeTwo; 
    } 

    public void setAttributeTwo(String attributeTwo) { 
     this.attributeTwo = attributeTwo; 
    } 

    public String getAttributeThree() { 
     return attributeThree; 
    } 

    public void setAttributeThree(String attributeThree) { 
     this.attributeThree = attributeThree; 
    } 

    public String getInnerObject() { 
     return innerObject; 
    } 

    public void setInnerObject(String innerObject) { 
     this.innerObject = innerObject; 
    } 
} 

最後に、私の依存関係は次のようになります。

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-web</artifactId> 
</dependency> 
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-test</artifactId> 
    <scope>test</scope> 
</dependency> 
<dependency> 
    <groupId>com.jayway.jsonpath</groupId> 
    <artifactId>json-path</artifactId> 
    <scope>test</scope> 
</dependency> 
<dependency> 
    <groupId>com.fasterxml.jackson.module</groupId> 
    <artifactId>jackson-module-jaxb-annotations</artifactId> 
    <version>2.5.0</version> 
</dependency> 
<dependency> 
     <groupId>com.fasterxml.jackson.dataformat</groupId> 
     <artifactId>jackson-dataformat-xml</artifactId> 
     <version>2.8.4</version> 
</dependency> 
<dependency> 
    <groupId>org.codehaus.woodstox</groupId> 
    <artifactId>woodstox-core-asl</artifactId> 
    <version>4.4.1</version> 
</dependency> 

これは、Woodstox」BufferingXmlWriterのジャクソンの使用に発生しているように見えます。この特定の作家は、これらの文字を傍受し、それらをコードし、その決定を回避するためにどのような方法があるように思われないだろう。

private final void writeAttrValue(String value, int len) throws IOException { 
    int inPtr = 0; 
    char qchar = this.mEncQuoteChar; 
    int highChar = this.mEncHighChar; 

    while(true) { 
     String ent = null; 

     while(true) { 
      if(inPtr >= len) { 
       return; 
      } 

      char c = value.charAt(inPtr++); 
      if(c <= 60) { 
       if(c < 32) { 
        if(c == 13) { 
         if(this.mEscapeCR) { 
          break; 
         } 
        } else { 
         if(c == 10 || c == 9 || this.mXml11 && c != 0) { 
          break; 
         } 

         c = this.handleInvalidChar(c); 
        } 
       } else { 
        if(c == qchar) { 
         ent = this.mEncQuoteEntity; 
         break; 
        } 

        if(c == 60) { 
         ent = "&lt;"; 
         break; 
        } 

        if(c == 38) { 
         ent = "&amp;"; 
         break; 
        } 
       } 
      } else if(c >= highChar) { 
       break; 
      } 

      if(this.mOutputPtr >= this.mOutputBufLen) { 
       this.flushBuffer(); 
      } 

      this.mOutputBuffer[this.mOutputPtr++] = c; 
     } 

     if(ent != null) { 
      this.writeRaw(ent); 
     } else { 
      this.writeAsEntity(value.charAt(inPtr - 1)); 
     } 
    } 
} 

だから、最後に問題をまとめるために、私は、XMLファイルを与えられています。そのXMLファイルには、XMLを破損しないように(&lt;&gt;)エンコードされたシンボル(と>)が含まれている属性と要素が含まれています。 Woodstoxがファイルを読み込むときに、JavaオブジェクトにXMLに含まれる実際の文字列を渡すのではなく、文字をデコードします。書き込み時に<のみが&lt;として再エンコードされます。これは、JacksonがWoodstoxのBufferingXmlWriterを使用しているために起こっているように見えますが、これらの文字のエンコードを避けるように設定することはできません。

その結果、私の質問は以下の通りです:

は私がさらにエンコードせずに私のXMLファイル内の文字を読み書きできるようになりますWoodstox XMLリーダーを使用し、または実行するためにジャクソンのオブジェクトを設定することができます私は自分のニーズに完全に違う解決策を探す必要がありますか?

答えて

0

にはCharacterEscapesを使用するように設定できます。デフォルトでエスケープされるものに上書きすることができます。

http://www.cowtowncoder.com/blog/archives/2012/08/entry_476.html

作品:これはでしょうか?

上記の提案のお詫び - これは、JSONだけのXMLでは機能しません。私はそれを二重にチェックすべきだった。 XMLでも動作させるための作業項目はありますが、これはまだ存在しません(2016年11月現在)。

+0

残念ながら、 https://github.com/FasterXML/jackson-dataformat-xml/issues/75によると、現在のビルドはキャラクタエスケープ機能をサポートしていません。私は無駄にそれを実装しようとしました。 –

+0

@MatthewSnookはい、いいえ:現在のバージョンは便利なアクセスをサポートしていません。 'XmlMapper'に対して特別に設定された' XMLOutputFactory2'を提供することを妨げるものは何もありません(または、おそらく 'XmlFactory'を介して、私は詳細を忘れてしまいます)。だから、使用する配線がもう少しありますが、それは実行可能でなければなりません。 – StaxMan

+0

ええと....さて、もう少し手引きが必要です。単にそのブログ記事からのプロセスに従うだけでは、実際には読み取り/書き込みデータに何もしないようです。 –

関連する問題