2010-11-29 16 views
27

XMLエクスポート機能を開発して、アプリケーションユーザーにデータをXML形式でエクスポートするようにしています。私はこの機能を準備しておき、場合によっては失敗するまで働いています。それから、エンコードする必要のある特殊文字が原因であることに気付きました。たとえば、データに&または!または%または 'または#などなど。これは適切にエスケープする必要があります。 XML仕様に従ってすべての特殊文字をエスケープできる一般的なユーティリティがあるかどうか疑問に思っていました。 Googleで何も見つかりませんでした。JavaでXMLを生成するときに特殊文字をエスケープする

既にそこには何かがありますか?またはそれを行う他の方法はありますか?


<Data> 
    <TimeStamp>2010-08-31 00:00:00.0</TimeStamp> 
    <[Name that needs to be encoded]>0.0</[Name that needs to be encoded]> 
    <Group_Average>1860.0</Group_Average> 
</Data> 

答えて

46

apache common lang libraryを使用すると、文字列をエスケープできます。

org.apache.commons.lang.StringEscapeUtils 

String escapedXml = StringEscapeUtils.escapeXml("the data might contain & or ! or % or ' or # etc"); 

しかし、あなたが探していることはvalid XML tag nameに任意の文字列を変換する方法です。 ASCII文字の場合、XMLタグ名は、_:a-zA-Zのいずれかで始まり、_の任意の数の文字で始まる必要があります。-

確かにライブラリがないと思いますあなたのためにこれを行う必要がありますので、任意の文字列をこのパターンにマッチさせるか、あるいはattritbueの値に変換する独自の関数を実装する必要があります。

<property name="no more need to be encoded, it should be handled by XML library">0.0</property> 
+0

感謝。これは便利なものですが、問題はそれだけです< > "& '私はより広範なものを探しています。私がエスケープしたい文字列は実際にノード名として使用されています。 XMLの質問 –

+2

XML標準のW3Cによると、要素タグとして使用できる文字数は限られています。一般ノードを作成し、ヘッダーを属性の値として追加することができます(例: gigadot

+0

要素タグ名の規則は次のとおりです。http://www.w3.org/TR/REC-xml/#NT-Name < >"& 'は含まれていません。 – gigadot

3

私はちょうど同じトピックをカバーするように思われる。この前の質問にあなたを呼びます:ここで

は私が


Document xmldoc = new DocumentImpl(); 
Element root = xmldoc.createElement("Report"); 

Element name= xmldoc.createElement((exportData.getChartName() == null) ? "Report" : exportData.getChartName()); 
if (exportData.getExportDataList().size() > 0 
    && exportData.getExportDataList().get(0) instanceof Vector) { 
    // First row is the HEADER, i.e name 
    Vector name = exportData.getExportDataList().get(0); 
    for (int i = 1; i value = exportData.getExportDataList().get(i); 
     Element sub_root = xmldoc.createElement("Data"); 
     //I had to remove a for loop from here. StackOverflow description field would not take that. :(
      // Insert header row 
      Element node = xmldoc.createElementNS(null, replaceUnrecognizedChars(name.get(j))); 
      Node node_value = xmldoc.createTextNode(value.get(j)); 
      node.appendChild(node_value); 
      sub_root.appendChild(node); 
      chartName.appendChild(sub_root); 
     } 
    } 
} 
root.appendChild(name); 

// Prepare the DOM document for writing 
Source source = new DOMSource(root); 

// Prepare the output file 
Result result = new StreamResult(file); 

// Write the DOM document to the file 
Transformer xformer = TransformerFactory.newInstance().newTransformer(); 
xformer.transform(source, result);` 

XMLを生成するために、サンプルXMLを使用していたコードは次のようになります。 Best way to encode text data for XML in Java?

1
public class RssParser { 
int length; 
    URL url; 
URLConnection urlConn; 
NodeList nodeList; 
Document doc; 
Node node; 
Element firstEle; 
NodeList titleList; 
Element ele; 
NodeList txtEleList; 
String retVal, urlStrToParse, rootNodeName; 

public RssParser(String urlStrToParse, String rootNodeName){ 
    this.urlStrToParse = urlStrToParse; 
    this.rootNodeName = rootNodeName; 

    url=null; 
    urlConn=null; 
    nodeList=null; 
    doc=null; 
    node=null; 
    firstEle=null; 
    titleList=null; 
    ele=null; 
    txtEleList=null; 
    retVal=null; 
      doc = null; 
    try { 
     url = new URL(this.urlStrToParse); 
        // dis is path of url which v'll parse 
     urlConn = url.openConnection(); 

        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 

     String s = isToString(urlConn.getInputStream()); 
     s = s.replace("&", "&amp;"); 
     StringBuilder sb = 
          new StringBuilder 
            ("<?xml version=\"1.0\" encoding=\"utf-8\"?>"); 
     sb.append("\n"+s); 
     System.out.println("STR: \n"+sb.toString()); 
     s = sb.toString(); 

     doc = db.parse(urlConn.getInputStream()); 
     nodeList = doc.getElementsByTagName(this.rootNodeName); 
     // dis is d first node which 
     // contains other inner element-nodes 
     length =nodeList.getLength(); 
     firstEle=doc.getDocumentElement(); 
    } 
    catch (ParserConfigurationException pce) { 
     System.out.println("Could not Parse XML: " + pce.getMessage()); 
    } 
    catch (SAXException se) { 
     System.out.println("Could not Parse XML: " + se.getMessage()); 
    } 
    catch (IOException ioe) { 
     System.out.println("Invalid XML: " + ioe.getMessage()); 
    } 
    catch(Exception e){ 
     System.out.println("Error: "+e.toString()); 
    } 
} 


public String isToString(InputStream in) throws IOException { 
    StringBuffer out = new StringBuffer(); 
    byte[] b = new byte[512]; 
    for (int i; (i = in.read(b)) != -1;) { 
     out.append(new String(b, 0, i)); 
    } 
    return out.toString(); 
} 

public String getVal(int i, String param){ 
    node =nodeList.item(i); 
    if(node.getNodeType() == Node.ELEMENT_NODE) 
    { 
     System.out.println("Param: "+param); 
     titleList = firstEle.getElementsByTagName(param); 
     if(firstEle.hasAttribute("id")) 
     System.out.println("hasAttrib----------------"); 
     else System.out.println("Has NOTNOT  NOT"); 
     System.out.println("titleList: "+titleList.toString()); 
    ele = (Element)titleList.item(i); 
    System.out.println("ele: "+ele); 
     txtEleList = ele.getChildNodes(); 
    retVal=(((Node)txtEleList.item(0)).getNodeValue()).toString(); 
    if (retVal == null) 
     return null; 
      System.out.println("retVal: "+retVal); 
    } 
return retVal; 
} 
} 
+0

このコードでは、私はパーサクラスを作成しました。そのうちのコンストラクタは2つのパラメータをとります。 1つ目はxmlファイルを読み込んだところからの入力ストリーム、2番目は最初の内部ノード名です。 isToStreamメソッドを使用して入力ストリームから文字列を取得する場合、このメソッドは文字列を返します。 この返された文字列内の1つの特殊文字 "&"を "&"に置き換え、xmlバージョンとエンコーディングを先頭に追加しました。 –