如何格式化此表达式,以便在运行for循环时,仅选择分析属性为空的位置。原因是有多个具有相同值的templateNames。这是我的尝试,但无法开始工作
String theXpath = "//report-plan[@name='"+ templateName +"']/settings/@analysis=''";
示例代码:
public class XPathTestReports {
public static void main(String[] args) {
try {
String outputFile = "c:/workspace/samplenew.xml";
String inputFile = "c:/workspace/sample.xml";
Document doc = DocumentBuilderFactory.newInstance()
.newDocumentBuilder().parse(new InputSource(inputFile));
// locate the node(s)
XPath xpath = XPathFactory.newInstance().newXPath();
// lOAD THE File
CSVImporterReports loader = new CSVImporterReports("C:/REPORT_TEMPLATES.csv");
List < OnConfig > entries = loader.getEntries();
for (OnConfig c: entries) {
String templateName = c.getTemplateName();
String analName = c.getAnalysisName();
String paramName = c.getParamName();
String theXpath = "//report-plan[@name='" + templateName + "']/settings/@analysis=''";
NodeList nodes = (NodeList) xpath.evaluate(theXpath, doc, XPathConstants.NODESET);
// make the change
for (int i = 0; i < nodes.getLength(); i++) {
nodes.item(i).setTextContent(analName);
// nodes.item(i).setTextContent(paramName);
}
}
try {
// save the result
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.transform(new DOMSource(doc), new StreamResult(new File(outputFile)));
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
} catch (TransformerFactoryConfigurationError e) {
// TODO Auto-generated catch block
} catch (TransformerException e) {
// TODO Auto-generated catch block
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
}
示例XML:
<report-plan name="generic">
<columns>
<column name="Nominal" subtotal-function="Sum" total-function="Sum"/>
<column name="Trade"/>
</columns>
<settings analysis="" analysisParameters="" filtering-enabled="true" object-actions="false" show-object-actions="true" sorting-enabled="true"/>
</report-plan>
<report-plan name="generic">
<columns>
<column name="Nominal" subtotal-function="Sum" total-function="Sum"/>
<column name="Trade"/>
</columns>
<settings analysis="" analysisParameters="" filtering-enabled="true" object-actions="false" show-object-actions="true" sorting-enabled="true"/>
</report-plan>
<report-plan name="sensitive">
<columns>
<column name="Nominal" subtotal-function="Sum" total-function="Sum"/>
<column name="Trade"/>
</columns>
<settings analysis="" analysisParameters="" filtering-enabled="true" object-actions="false" show-object-actions="true" sorting-enabled="true"/>
</report-plan>
目前,我的代码为两个名为generic的报告输入了相同的值。即使分析属性具有要输入的不同值。即使报告名称相同,我也需要输入不同分析值的代码。
输出:
<report-plan name="generic">
<columns>
<column name="Nominal" subtotal-function="Sum" total-function="Sum"/>
<column name="Trade"/>
</columns>
<settings analysis="newValue" analysisParameters="" filtering-enabled="true" object-actions="false" show-object-actions="true" sorting-enabled="true"/>
</report-plan>
<report-plan name="generic">
<columns>
<column name="Nominal" subtotal-function="Sum" total-function="Sum"/>
<column name="Trade"/>
</columns>
<settings analysis="newValue" analysisParameters="" filtering-enabled="true" object-actions="false" show-object-actions="true" sorting-enabled="true"/>
</report-plan>
<report-plan name="sensitive">
<columns>
<column name="Nominal" subtotal-function="Sum" total-function="Sum"/>
<column name="Trade"/>
</columns>
<settings analysis="someValue" analysisParameters="" filtering-enabled="true" object-actions="false" show-object-actions="true" sorting-enabled="true"/>
</report-plan>
CSV样本
TEMPLATE_NAME ANALYSIS_NAME PARAM_NAME
generic analval1 paramval1
generic analval2 paramval2
sensitivity analval3 paramval3
答案 0 :(得分:3)
好的,我想我知道你在这里会发生什么。您希望使用XPath为您提供存在且为空的@analysis节点,以便您可以使用某些已配置的值填充它们。
String theXpath = "//report-plan[@name='" + templateName + "']/settings/@analysis[.='']";
编辑添加:
现在,请记住,这将为模板名称选择所有@analysis节点。当您执行第二级for
循环时,您正在更改所有这些循环。在下一个名为“generic”的CSV上,它将找不到要更改的节点。
替换:
for (int i = 0; i < nodes.getLength(); i++) {
nodes.item(i).setTextContent(analName);
}
使用:
if (nodes.getLength() > 0) {
nodes.item(0).setTextContent(analName);
}
答案 1 :(得分:1)
也许你的意思是
String theXpath = "//report-plan[@name='"+ templateName +"' and not(settings/@analysis > '')]";
这将选择具有特定名称但不包含<report-plan>
(或空名称)的所有settings/@analysis
元素。