有人可以找到此代码的错误。无论我选择哪种XPath,它总是返回空字符串
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("chart.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
String str = (String) xpath.evaluate("/row[@id='1']", doc.getDocumentElement(), XPathConstants.STRING);
System.out.println("xml string is"+str);
我的chart.xml是
<?xml version="1.0" encoding="iso-8859-1"?>
<chart>
<row id="1">
<Select numofobjects="0" id="1000" index="1">
<Table alias="ConvertDetails" name="ConvertDetails"/>
</Select>
</row>
<row id="2">
<Select numofobjects="0" id="2000" index="2">
<Table alias="ConvertDetails" name="ConvertDetails"/>
</Select>
</row>
</chart>
我的预期输出是
<Select numofobjects="0" id="1000" index="1">
<Table alias="ConvertDetails" name="ConvertDetails"/>
</Select>
答案 0 :(得分:2)
正如Martin指出的那样,你需要选择一个节点,而不是它的字符串值:
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("chart.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
Node n = (Node) xpath.evaluate("row[@id='1']", doc.getDocumentElement(),
XPathConstants.NODE);
然后您可以使用以下序列化帮助方法(借鉴Get a node's inner XML as String in Java DOM):
public static String innerXml(Node node) {
DOMImplementationLS lsImpl = (DOMImplementationLS)node.getOwnerDocument()
.getImplementation()
.getFeature("LS", "3.0");
LSSerializer lsSerializer = lsImpl.createLSSerializer();
lsSerializer.getDomConfig().setParameter("xml-declaration", false);
NodeList childNodes = node.getChildNodes();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < childNodes.getLength(); i++) {
sb.append(lsSerializer.writeToString(childNodes.item(i)));
}
return sb.toString();
}
像这样:
String xmlStr = "";
if (n != null) {
xmlStr = innerXml(node);
}
答案 1 :(得分:0)
如果要选择节点,请不要使用XPathConstants.STRING
,因为它会获取所选节点的字符串内容,并且所有元素都为空。您需要选择节点或节点集,并确保在需要其标记时序列化节点。
答案 2 :(得分:0)
使用@ JLRishe的代码完美无缺(+1)。
问题在于您的XML文档。您关闭了<Select>
代码错误(使用</SelectOne>
\ </SelectTwo>
)。
尝试在以下XML上运行此代码:
<强>代码:强>
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
public class XMLSerializer {
public static void main(String[] args) {
try {
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse("chart.xml");
XPath xpath = XPathFactory.newInstance().newXPath();
Node n = (Node) xpath.evaluate("row[@id='1']", doc.getDocumentElement(),
XPathConstants.NODE);
String xmlStr = "";
if (n != null) {
xmlStr = innerXml(n);
System.out.println("xml string is"+xmlStr);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static String innerXml(Node node) {
DOMImplementationLS lsImpl = (DOMImplementationLS)node.getOwnerDocument()
.getImplementation()
.getFeature("LS", "3.0");
LSSerializer lsSerializer = lsImpl.createLSSerializer();
lsSerializer.getDomConfig().setParameter("xml-declaration", false);
NodeList childNodes = node.getChildNodes();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < childNodes.getLength(); i++) {
sb.append(lsSerializer.writeToString(childNodes.item(i)));
}
return sb.toString();
}
}
<强> XML:强>
<?xml version="1.0" encoding="iso-8859-1"?>
<chart>
<row id="1">
<Select numofobjects="0" id="1000" index="1">
<Table alias="ConvertDetails" name="ConvertDetails"/>
</Select>
</row>
<row id="2">
<Select numofobjects="0" id="2000" index="2">
<Table alias="ConvertDetails" name="ConvertDetails"/>
</Select>
</row>
</chart>