1

入力XMLでXSL変換を行っているので、結果のドキュメントでXPathを使用していくつかの値を抽出する必要があります。ただし、XSL結果ノードを使用する場合、XPath式が常にnullを返す場合があります。しかし、XSLの結果のドキュメントをファイルに保存した場合は、それをリロードします。XPath式は、対応するノードを返します。

これが私のコードです(ユーティリティ関数は責任のために削除されました):

public class XmlTest {
@Test
public void testWithNativeJavaApi() throws Exception {
    InputStream instream = resolveClasspathFile("xslt/xslt-test-transform-2.xsl");
    StreamSource xsltSource = new StreamSource(instream);
    DOMSource domSource = loadXmlFromClasspathFile("xslt/xslt-test-input-2.xml");
    prettyPrint(domSource.getNode());

    Transformer transformer = TransformerFactory.newInstance().newTransformer(xsltSource);
    DOMResult domResult = new DOMResult();
    transformer.transform(domSource, domResult);
    Node node = domResult.getNode();

    // Store then reload the file
    // Uncommenting those 3 lines will make the test pass
    // File xslOutputfile = new File("target", "xsl-ouput.xml");
    // prettyPrint(node, new FileOutputStream(xslOutputfile));
    // node = loadXmlFromInputStream(new FileInputStream(xslOutputfile)).getNode();

    XPath xPathProcessor = XPathFactory.newInstance().newXPath();
    XPathExpression xpathExpression = xPathProcessor.compile("/Message/Out/Personne/CodeCivilite");
    System.out.println();
    Node resultNode = (Node) xpathExpression.evaluate(node, XPathConstants.NODE);

    if (resultNode != null) {
        System.out.println(resultNode.getNodeName() + "=" + resultNode.getTextContent());
    } else {
        System.out.println("Node is null");
    }

    assertNotNull("XPath expression returned null node", resultNode);
    assertEquals("CodeCivilite", resultNode.getNodeName());
    assertEquals("M.", resultNode.getTextContent());

}
}

コメントするか、「//保存してからファイルをリロードする」の下の3行を削除すると、テストに合格しなくなります。

私は完全に立ち往生しています、どんな助けでも大歓迎です。

4

3 に答える 3

1

DocumentBuilderFactoryは、dbf.setNamespaceAware(true)が使用されていない限り、デフォルトで名前空間を使用しません。一方、XSLとTransformerFactoryは名前空間を多用するため、変換の結果のドキュメントは名前空間で修飾されます。

したがって、XPathExpressionは、XSL変換の隣で呼び出されるときに名前空間を使用する必要があります。

XPath xPathProcessor = XPathFactory.newInstance().newXPath();
xPathProcessor.setNamespaceContext(new NamespaceContext() {
  @Override
  public String getNamespaceURI(String prefix) {
    if(prefix.equals("t")) {
      return "http://www.example.org/test";
    } else {
      return null;  
    }
  }
  @Override public String getPrefix(String namespaceURI) {
    return null; // not used
  }
  @Override
  public Iterator<?> getPrefixes(String namespaceURI) {
    return null; // not used
  }
});
XPathExpression xpathExpression = xPathProcessor.compile("/t:Message/t:Out/t:Personne/t:CodeCivilite");
System.out.println();
Node resultNode = (Node) xpathExpression.evaluate(node, XPathConstants.NODE);

デフォルトのDocumentBuilderFactory(名前空間を認識しない)で再ロードされた一時ファイルを導入すると、非修飾XPATH式(名前空間なし)が機能します。

これが明確であることを願っています:)

于 2012-07-25T06:58:48.460 に答える
0

ファイルを解析すると、ツリーが短くなるのではないかと思います。xpath式を使用してみてください

//Message/Out/Personne/CodeCivilite

(前にダブルスラッシュ)ファイルI / Oなしで、ファイルI/Oなしのノードの余分なレイヤーがあるかどうかを確認します。

于 2012-07-23T19:51:58.400 に答える
0

node = loadXmlFromInputStream(new FileInputStream(xslOutputfile))。getDocumentElement();

getDocumentElement()ですか?

リロードされたノードを印刷して、期待どおりのものがあるかどうかを確認できますか?

于 2012-07-23T19:59:52.000 に答える