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