3

xsi:nil="true"のいくつかのxmlタグを含む次のxmlがあります。これらは基本的にnullのタグです。sxltトランスフォーマーを使用/検索してこれらのタグをxmlから削除し、残りのxmlを取得することができません。

<?xml version="1.0" encoding="utf-8"?>
<p849:retrieveAllValues xmlns:p849="http://package.de.bc.a">
    <retrieveAllValues>
        <messages xsi:nil="true" />
        <existingValues>
            <Values>
                <value1> 10.00</value1>
                <value2>123456</value2>
                <value3>1234</value3>
                <value4 xsi:nil="true" />
                <value5 />
            </Values>
        </existingValues>
        <otherValues xsi:nil="true" />
        <recValues xsi:nil="true" />
    </retrieveAllValues>
</p849:retrieveAllValues>
4

2 に答える 2

4

あなたが得るエラーの理由

[致命的なエラー]file2.xml:5:30:要素タイプ「messages」に関連付けられた属性「xsi:nil」のプレフィックス「xsi」がバインドされていません。

「xsi」という名前のプレフィックスが宣言されていない場合は、次のようなルート要素で指定する必要があります。

<p849:retrieveAllValues xmlns:p849="http://package.de.bc.a"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<retrieveAllValues>
    <messages xsi:nil="true" />
       // other code...

アップデート

Webサービスから受け取っているxmlドキュメントを変更できない場合は、次のアプローチを試すことができます(このアプローチが受け入れられる場合)。

  1. xslt要素プレフィックスを指定せずにxmlドキュメントを処理するようにドキュメントを変更します
  2. のプロパティをfalseに設定namespaceAwareDocumentBuilderFactoryます

この後、あなたのトランスフォーマーは文句を言うべきではありません

于 2013-02-13T19:21:42.587 に答える
1

これがXSLTで可能になるとは思えません-名前空間宣言がないため、名前空間を認識しないパーサーでXMLファイルを解析する必要がありますが、私が試したすべてのXSLTプロセッサーは取得できませんこのようなドキュメントでは、問題のドキュメントに実際に名前空間ノードが含まれていない場合でも、名前空間認識を有効にして解析する場合にのみ存在する情報に依存する必要があります。

そのため、たとえばDOMツリーを自分でトラバースするなど、別の方法でアプローチする必要があります。Javaで作業していると言うので、Java DOM APIを使用した例を次に示します(例はGroovyコンソールでそのまま実行するか、適切なクラス定義にまとめて、Javaとして実行するために必要な例外処理を追加します。 )。

import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.w3c.dom.ls.*;

public void stripNils(Node n) {
  if(n instanceof Element &&
      "true".equals(((Element)n).getAttribute("xsi:nil"))) {
    // element is xsi:nil - strip it out
    n.getParentNode().removeChild(n);
  } else {
    // we're keeping this node, process its children (if any) recursively
    NodeList children = n.getChildNodes();
    for(int i = 0; i < children.getLength(); i++) {
      stripNils(children.item(i));
    }
  }
}

// load the document (NB DBF is non-namespace-aware by default)
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document xmlDoc = db.parse(new File("input.xml"));

stripNils(xmlDoc);

// write out the modified document, in this example to stdout
LSSerializer ser =
  ((DOMImplementationLS)xmlDoc.getImplementation()).createLSSerializer();
LSOutput out =
  ((DOMImplementationLS)xmlDoc.getImplementation()).createLSOutput();
out.setByteStream(System.out);
ser.write(xmlDoc, out);

元のサンプルXMLでは、これにより正しい結果が生成されます。

<?xml version="1.0" encoding="UTF-8"?>
<p849:retrieveAllValues xmlns:p849="http://package.de.bc.a">
    <retrieveAllValues>

        <existingValues>
            <Values>
                <value1> 10.00</value1>
                <value2>123456</value2>
                <value3>1234</value3>

                <value5/>
            </Values>
        </existingValues>


    </retrieveAllValues>
</p849:retrieveAllValues>

空の行は実際には空ではありません。ここでは要素自体のみが削除されているため、削除された要素の両側に空白のテキストノードが含まれています。

于 2013-02-14T15:12:27.017 に答える