2

xmlファイルを解析する必要があります(JAXBを使用して解析します)が、Xmlファイル値の一部を文字列に取り込みたいです。ネットサーフィンした後は、CDATAを使用することで可能になります。次のリンクはCDATAについて説明しています。しかし、私はコードに疑問を持っています。どの要素をCDATAとして処理するかをどこでどのように指定する必要がありますか。

http://jaxb.java.net/faq/JaxbCDATASample.java

私のXMLは次のようになります。

<root>
    <Service>CDATASERVICE</Service>
    <Child>
        <param>
            <value>
                <struct>
                    <member>
                        <name>Servicename</name>
                        <value>service1</value>
                    </member>
                </struct>
            </value>
        </param>
        <param>
            <value>
                <struct>
                    <member>
                        <name>item1</name>
                        <value>36</value>
                    </member>
                    <member>
                        <name>Cdata</name>
                        <value>
                            <struct>
                                <member>
                                    <name>services</name>
                                    <value>
                                        <array>
                                            <data>
                                                <value>ABCD</value>
                                            </data>
                                        </array>
                                    </value>
                                </member>
                            </struct>
                        </value>
                    </member>
                    <member>
                        <name>item2</name>
                        <value>
                            <int>10</int>
                        </value>
                    </member>
                </struct>
            </value>
        </param>
    </Child>
</root>

上記のXMLファイルから次の部分を文字列として取得したいのですが、どうすれば取得できますか。

                 <name>Cdata</name>
                            <value>
                                <struct>
                                    <member>
                                        <name>services</name>
                                        <value>
                                            <array>
                                                <data>
                                                    <value>ABCD</value>
                                                </data>
                                            </array>
                                        </value>
                                    </member>
                                </struct>
                            </value>
4

2 に答える 2

1

このユースケースに指定された@XmlAnyElementでを使用できます。DomHandler

MemberHandler

注釈@XmlAnyElementを使用すると、XMLドキュメントの一部をXMLとして保持できます。デフォルトでは、これはDOMノードとして保持されます。を実装するDomHandlerことにより、などの代替表現を活用できますString

package forum12512299;

import java.io.*;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.annotation.DomHandler;
import javax.xml.transform.Source;
import javax.xml.transform.stream.*;

public class MemberHandler implements DomHandler<String, StreamResult> {

    private static final String MEMBER_START_TAG = "<member>";
    private static final String MEMBER_END_TAG = "</member>";

    private StringWriter xmlWriter;

    public StreamResult createUnmarshaller(ValidationEventHandler errorHandler) {
        xmlWriter = new StringWriter();
        return new StreamResult(xmlWriter);
    }

    public String getElement(StreamResult rt) {
        String xml = rt.getWriter().toString();
        int beginIndex = xml.indexOf(MEMBER_START_TAG) + MEMBER_START_TAG.length();
        int endIndex = xml.indexOf(MEMBER_END_TAG);
        return xml.substring(beginIndex, endIndex);
    }

    public Source marshal(String n, ValidationEventHandler errorHandler) {
        try {
            String xml = MEMBER_START_TAG + n.trim() + MEMBER_END_TAG;
            StringReader xmlReader = new StringReader(xml);
            return new StreamSource(xmlReader);
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

}

構造体

以下は、マッピングDomHandlerからの参照方法の例です。@XmlAnyElement

package forum12512299;

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement
public class Struct {

    private List<String> members;

    @XmlAnyElement(MemberHandler.class)
    public List<String> getMembers() {
        return members;
    }

    public void setMembers(List<String> members) {
        this.members = members;
    }

}

input.xml

以下に、XMLドキュメントを興味深い部分まで簡略化しました。

<struct>
    <member>
        <name>item1</name>
        <value>36</value>
    </member>
    <member>
        <name>Cdata</name>
        <value>
            <struct>
                <member>
                    <name>services</name>
                    <value>
                        <array>
                            <data>
                                <value>ABCD</value>
                            </data>
                        </array>
                    </value>
                </member>
            </struct>
        </value>
    </member>
    <member>
        <name>item2</name>
        <value>
            <int>10</int>
        </value>
    </member>
</struct>

デモ

package forum12512299;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Struct.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xml = new File("src/forum12512299/input.xml");
        Struct struct = (Struct) unmarshaller.unmarshal(xml);

        for(String string : struct.getMembers()) {
            System.out.println(string);
        }
    }

}

出力

<name>item1</name><value>36</value>

<name>Cdata</name><value><struct><member><name>services</name><value><array><data><value>ABCD</value>
                            </data>
                        </array>
                    </value>

<name>item2</name><value><int>10</int>
        </value>
于 2012-09-20T13:26:29.110 に答える
-1

質問のタイトルにあるCDATAへの言及は誤解を招く恐れがあります。XMLのCDATAセクションは、次のように記述されたXMLファイルの一部です。

<![CDATA[ … ]]>

そのセクションのコンテンツはXMLとして解析されず、代わりに生の文字テキストとして扱われます。したがって、それはその部分&lt;のすべてのために書くことに代わるものです。<

CDATAはXML情報セットの一部ではありません。ほとんどのアプリケーションは、入力テキストがCDATAセクションとして記述されているのか、「通常の」テキストとして記述されているのか、またはこれら2つの混合として記述されているのかを気にしません。実際のシリアル化されたファイル表現の非常に低いレベルでのみ、空白、インデント、文字エンコードなども処理しますが、CDATAは重要です。これがあなたが参照した例です。明らかに、特定の文字列をCDATAセクションまたは文字参照を含む「通常の」XMLとしてレンダリングする必要があることをJAXBに通知する方法があります。

アプリケーションにとって、これはほとんど役に立たないようです。CDATAを利用するには、入力XMLにCDATAマークアップがすでに含まれている必要があります。(私たちの例によれば)そうではないので、パーサーはそれを整形式のXMLとして扱う以外に選択肢はありません。Blaiseの回答は、データ構造内でそのサブツリーをDOMノードまたはXML文字列として「そのまま」表現できる可能性があることをすでに指摘しています。

于 2012-09-20T14:33:09.343 に答える