在 Java 中使用 EvaluateXpath 返回缺失标签的空值
Returning Null values for missing tags with EvaluateXpath in Java
我正在通过评估路径检索 XML 标签值,假设我有 3 个带有图书信息的标签:
书籍信息包括:姓名 - 年份 - 作者和 1 个标签作者姓名已丢失且未出现在我的标签中,我想要一个显示 1 个作者姓名 + 空值的数组,这表明 2 个标签没有已指定,如下所示:
如您所见,第二个标签不包含作者姓名,第三个标签没有任何作者姓名标签,如下所示:
我非常感谢任何指导/提示/帮助。 :-)
Author:
[John Smith,null,null]
我的 XML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<perldata>
<item key="book">
<item key="name">My Book Name</item>
<item key="year">2019</item>
<item key="author">John Smith</item>
</item>
<item>
<item key="name">Anonymous Book Name 1</item>
<item key="year">2018</item>
<item key="author"></item>
</item>
<item>
<item key="name">Her Book Name</item>
<item key="year">2018</item>
</item>
</perldata>
这表明第三个标签不包含作者姓名标签。
我不知道如何在 EvaluateXpath 中显示空值:(真的需要帮助)
String fileName="book.xml";
Document document = getDocument(fileName);
// Defining Variables
// String xpathExpression = "";
FileWriter fw = null;
BufferedWriter bw = null;
PrintWriter pw = null;
//Using Document Builder
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc1 = documentBuilder.parse(fileName);
/*******Get attribute values using xpath******/
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
try{
fw = new FileWriter("/root/Desktop/book.txt");
bw = new BufferedWriter(fw);
pw = new PrintWriter(bw)
pw.println("BookName: "+evaluateXpath(document, "/perldata/item[@key=book]/item[@key='name']/text()"));
pw.println("year: "+evaluateXpath(document, "/perldata/item[@key=book]/item[@key='year']/text()"))
pw.println("Author: "+evaluateXpath(document, "/perldata/item[@key=book]/item[@key='author']/text()"))
pw.flush(); }
catch (IOException e)
{ e.printStackTrace(); } } }
private static List<String> evaluateXPath(Document document, String xpathExpression) throws Exception
{
// Create XPathFactory object
XPathFactory xpathFactory = XPathFactory.newInstance();
// Create XPath object
XPath xpath = xpathFactory.newXPath();
List<String> values = new ArrayList<>();
try
{
// Create XPathExpression object
XPathExpression expr = xpath.compile(xpathExpression);
// Evaluate expression result on XML document
NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
values.add(nodes.item(i).getNodeValue());
}
} catch (XPathExpressionException e) {
e.printStackTrace();
}
return values;
}
private static Document getDocument(String fileName) throws Exception
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(fileName);
return doc;
}
}
总结:
Trim标签的文本内容,判断结果字符串是否为空
详情:
问题中的XML只有一个标签包含key="book"
。我假设所有 3 个部分都应该有这个,所以我们知道每个部分代表一本书。
因此,我假设您有一个如下所示的 XML 文件,其中包括一个空的“作者”标签和一个完全缺失的“作者”标签:
<?xml version="1.0" encoding="UTF-8"?>
<perldata>
<item key="book">
<item key="name">My Book Name</item>
<item key="year">2019</item>
<item key="author">John Smith</item>
</item>
<item key="book">
<item key="name">Anonymous Book Name 1</item>
<item key="year">2018</item>
<item key="author"></item>
</item>
<item key="book">
<item key="name">Her Book Name</item>
<item key="year">2018</item>
</item>
<item key="book">
<item key="name">Another Book Name</item>
<item key="year">2019</item>
<item key="author">Jane Jones</item>
</item>
</perldata>
假设如上,可以打印出所有名字(包括null
个名字)如下:
File file = new File("C:/tmp/Book2.xml");
FileInputStream fis = new FileInputStream(file);
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(fis);
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList bookNodes = (NodeList) xPath.compile("//item[@key='book']")
.evaluate(xmlDocument, XPathConstants.NODESET);
List<String> authors = new ArrayList();
for (int i = 0; i < bookNodes.getLength(); i++) {
Node bookNode = bookNodes.item(i);
Node authorNode = (Node) xPath.compile("./item[@key='author']")
.evaluate(bookNode, XPathConstants.NODE);
if (authorNode == null) {
authors.add(null);
} else {
String s = authorNode.getTextContent().trim();
authors.add(s.isEmpty() ? null : s);
}
}
System.out.println(authors);
最后的打印语句是这样的:
[John Smith, null, null, Jane Jones]
补充说明:
这将循环遍历文件中的所有 <item key="book">
部分。对于每个部分,它然后执行此目标搜索,但 仅在该部分:
Node authorNode = (Node) xPath.compile("./item[@key='author']")
.evaluate(bookNode, XPathConstants.NODE);
evaluate
使用当前bookNode
作为起点。
之后,我们可以检查所有可能的结果:
- 我们找到了一个
key="author"
标签 - 它包含作者姓名。
- 我们找到了一个
key="author"
标签 - 但其中没有名称。
- 此
book
节点没有 key="author"
标签。
我正在通过评估路径检索 XML 标签值,假设我有 3 个带有图书信息的标签: 书籍信息包括:姓名 - 年份 - 作者和 1 个标签作者姓名已丢失且未出现在我的标签中,我想要一个显示 1 个作者姓名 + 空值的数组,这表明 2 个标签没有已指定,如下所示: 如您所见,第二个标签不包含作者姓名,第三个标签没有任何作者姓名标签,如下所示: 我非常感谢任何指导/提示/帮助。 :-)
Author: [John Smith,null,null]
我的 XML 文件:
<?xml version="1.0" encoding="UTF-8"?>
<perldata>
<item key="book">
<item key="name">My Book Name</item>
<item key="year">2019</item>
<item key="author">John Smith</item>
</item>
<item>
<item key="name">Anonymous Book Name 1</item>
<item key="year">2018</item>
<item key="author"></item>
</item>
<item>
<item key="name">Her Book Name</item>
<item key="year">2018</item>
</item>
</perldata>
这表明第三个标签不包含作者姓名标签。 我不知道如何在 EvaluateXpath 中显示空值:(真的需要帮助)
String fileName="book.xml";
Document document = getDocument(fileName);
// Defining Variables
// String xpathExpression = "";
FileWriter fw = null;
BufferedWriter bw = null;
PrintWriter pw = null;
//Using Document Builder
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document doc1 = documentBuilder.parse(fileName);
/*******Get attribute values using xpath******/
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
try{
fw = new FileWriter("/root/Desktop/book.txt");
bw = new BufferedWriter(fw);
pw = new PrintWriter(bw)
pw.println("BookName: "+evaluateXpath(document, "/perldata/item[@key=book]/item[@key='name']/text()"));
pw.println("year: "+evaluateXpath(document, "/perldata/item[@key=book]/item[@key='year']/text()"))
pw.println("Author: "+evaluateXpath(document, "/perldata/item[@key=book]/item[@key='author']/text()"))
pw.flush(); }
catch (IOException e)
{ e.printStackTrace(); } } }
private static List<String> evaluateXPath(Document document, String xpathExpression) throws Exception
{
// Create XPathFactory object
XPathFactory xpathFactory = XPathFactory.newInstance();
// Create XPath object
XPath xpath = xpathFactory.newXPath();
List<String> values = new ArrayList<>();
try
{
// Create XPathExpression object
XPathExpression expr = xpath.compile(xpathExpression);
// Evaluate expression result on XML document
NodeList nodes = (NodeList) expr.evaluate(document, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
values.add(nodes.item(i).getNodeValue());
}
} catch (XPathExpressionException e) {
e.printStackTrace();
}
return values;
}
private static Document getDocument(String fileName) throws Exception
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(fileName);
return doc;
}
}
总结:
Trim标签的文本内容,判断结果字符串是否为空
详情:
问题中的XML只有一个标签包含key="book"
。我假设所有 3 个部分都应该有这个,所以我们知道每个部分代表一本书。
因此,我假设您有一个如下所示的 XML 文件,其中包括一个空的“作者”标签和一个完全缺失的“作者”标签:
<?xml version="1.0" encoding="UTF-8"?>
<perldata>
<item key="book">
<item key="name">My Book Name</item>
<item key="year">2019</item>
<item key="author">John Smith</item>
</item>
<item key="book">
<item key="name">Anonymous Book Name 1</item>
<item key="year">2018</item>
<item key="author"></item>
</item>
<item key="book">
<item key="name">Her Book Name</item>
<item key="year">2018</item>
</item>
<item key="book">
<item key="name">Another Book Name</item>
<item key="year">2019</item>
<item key="author">Jane Jones</item>
</item>
</perldata>
假设如上,可以打印出所有名字(包括null
个名字)如下:
File file = new File("C:/tmp/Book2.xml");
FileInputStream fis = new FileInputStream(file);
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDocument = builder.parse(fis);
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList bookNodes = (NodeList) xPath.compile("//item[@key='book']")
.evaluate(xmlDocument, XPathConstants.NODESET);
List<String> authors = new ArrayList();
for (int i = 0; i < bookNodes.getLength(); i++) {
Node bookNode = bookNodes.item(i);
Node authorNode = (Node) xPath.compile("./item[@key='author']")
.evaluate(bookNode, XPathConstants.NODE);
if (authorNode == null) {
authors.add(null);
} else {
String s = authorNode.getTextContent().trim();
authors.add(s.isEmpty() ? null : s);
}
}
System.out.println(authors);
最后的打印语句是这样的:
[John Smith, null, null, Jane Jones]
补充说明:
这将循环遍历文件中的所有 <item key="book">
部分。对于每个部分,它然后执行此目标搜索,但 仅在该部分:
Node authorNode = (Node) xPath.compile("./item[@key='author']")
.evaluate(bookNode, XPathConstants.NODE);
evaluate
使用当前bookNode
作为起点。
之后,我们可以检查所有可能的结果:
- 我们找到了一个
key="author"
标签 - 它包含作者姓名。 - 我们找到了一个
key="author"
标签 - 但其中没有名称。 - 此
book
节点没有key="author"
标签。