gpt4 book ai didi

java - XSL 转换,然后在结果节点上进行 XPath 表达式

转载 作者:太空宇宙 更新时间:2023-11-04 08:08:48 25 4
gpt4 key购买 nike

我正在对输入 XML 进行 XSL 转换,然后需要在结果文档上使用 XPath 提取一些值。但是,当使用 XSL 结果 Node 时,XPath 表达式可能总是返回 null。但是,如果我将 XSL 结果文档存储在文件中,然后重新加载它。 XPath 表达式返回相应的 Node。

这是我的代码(为了方便起见,实用功能已被删除):

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());

}
}

只需注释或删除“//Store then reload the file”下面的 3 行,测试将不再通过。

我完全陷入困境,欢迎任何帮助。

最佳答案

DocumentBuilderFactory 默认情况下不使用命名空间,除非使用 dbf.setNamespaceAware(true)。另一方面,XSL 和 TransformerFactory 大量使用命名空间,因此转换的结果文档是用命名空间限定的。

因此,在 XSL 转换旁边调用 XPathExpression 时应该使用命名空间。

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 表达式(没有命名空间)起作用。

希望这是清楚的:)

关于java - XSL 转换,然后在结果节点上进行 XPath 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11614548/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com