1

次のように、ルート要素で version 属性を使用してバージョン番号を宣言する XML ドキュメントの読み取りと検証を処理するコードを記述する必要があります。

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<Junk xmlns="urn:com:initech:tps" 
    xmlns:xsi="http://www3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="urn:com:initech.tps:schemas/foo/Junk.xsd"
    VersionAttribute="2.0">

ネストされたスキーマがたくさんあります。私のコードには、org.w3c.dom.ls.LsResourceResolver使用するスキーマを見つけて、このメソッドを実装する必要があります。

LSInput resolveResource(String type,
                        String namespaceURI,
                        String publicId,
                        String systemId,
                        String baseURI)

以前のバージョンのスキーマでは、スキーマのバージョンが名前空間に埋め込まれていたため、namespaceURI と systemId を使用して、提供するスキーマを決定できました。現在、バージョン番号はルート要素の属性に切り替えられており、私のリゾルバーはそれにアクセスできません。内の XML ドキュメントのバージョンを確認するにはどうすればよいですLsResourceResolverか?

4

2 に答える 2

4

これまでスキーマのバージョンを扱う必要がなかったので、何が関係しているのかわかりませんでした。バージョンが名前空間の一部であった場合、すべてのスキーマを一緒に投入して整理することができますが、ルート要素内のバージョンとバージョン間で共有される名前空間では、事前に XML からバージョン情報を読み取ることはできません SAX 解析を開始します。

Pangea が提案したことと非常によく似たことを実行します (私から +1 を取得します) が、ドキュメントが大きすぎて一度でもすべてをメモリに読み込むことができないため、アドバイスを正確に実行することはできません。STAX を使用することで、ファイルからバージョンを取得する作業を最小限に抑えることができます。この DeveloperWorks の記事「StAX を使用して効率的に XML ドキュメントを選別する」を参照してください。

XML 文書のスクリーニングまたは分類は、特に XML ミドルウェアでよくある問題です。XML ドキュメントを特定のプロセッサにルーティングするには、ドキュメント タイプとドキュメント コンテンツの両方の分析が必要になる場合があります。ここでの問題は、最小限のオーバーヘッドでドキュメントから必要な情報を取得することです。DOM や SAX などの従来のパーサーは、このタスクにはあまり適していません。たとえば、DOM はドキュメント全体を解析し、完全なドキュメント ツリーをメモリ内に構築してから、クライアントに制御を返します。遅延ノード展開を採用していて、ドキュメントを部分的に解析できる DOM パーサーでさえ、ドキュメント ツリーは少なくとも部分的にメモリ内に構築する必要があるため、高いリソースを必要とします。これは、スクリーニング目的では受け入れられません。

バージョン情報を取得するコードは次のようになります。

def map = [:]
def startElementCount = 0
def inputStream = new File(inputFile).newInputStream()
try {
    XMLStreamReader reader = 
        XMLInputFactory.newInstance().createXMLStreamReader(inputStream)
    for (int event; (event = reader.next()) != XMLStreamConstants.END_DOCUMENT;) {
        if (event == XMLStreamConstants.START_ELEMENT) {
            if (startElementCount > 0) return map
            startElementCount += 1
            map.rootElementName = reader.localName
            for (int i = 0; i < reader.attributeCount; i++) {
                if (reader.getAttributeName(i).toString() == 'VersionAttribute') {
                    map.versionIdentifier = reader.getAttributeValue(i).toString()
                    return map
                }
            }
        }
    }   
} finally {
    inputStream.close()
}

次に、バージョン情報を使用して、使用するリゾルバーと、SaxFactory に設定するスキーマ ドキュメントを特定できます。

于 2012-08-17T20:39:46.093 に答える
3

私のおすすめ

  1. SAXまたはDOMを使用してドキュメントを解析します
  2. バージョン属性を取得する
  3. Validator.validate(Source)メソッドを使用し、以下に示すように、すでに解析されたドキュメント(ステップ1から)を使用します

解析されたドキュメントからのDOMSourceの構築

DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File(args[0]));

domSource = new DOMSource(document);
于 2012-08-17T14:00:58.027 に答える