2015-04-30 33 views
1

如何对此表达式进行格式设置,以便在for循环运行时仅选择分析属性为空的位置。原因是有多个具有相同值的templateNames。这是我的尝试,但不能去上班Xpath仅选择具有空值的属性

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> 

目前我的代码输入两个相同的值报告命名为通用。即使分析属性具有不同的输入值。即使报告名称相同,我也需要输入不同分析值的代码。

输出:

<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

有什么不对您当前的XPath? – har07

+1

只有在“分析”属性为空时才选择_what exactly_? –

+0

只在该报告计划元素中选择该分析属性。有多个报告计划元素,其中一些具有值,另一些是空的,所以我只选择那些空的。已更新以显示相关代码。 – Kelv

回答

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); 
} 
+0

是的。然而,这个表达式不起作用,因为分析属性仍然被配置为具有相同名称的模板的重复值。我的代码应该读取csv的下一行,其中包含相同的templateName,但包含应该配置的分析属性的不同值。 – Kelv

+0

然后看到我编辑的答案。 – bjimba

+0

谢谢你,这个伎俩! – Kelv

1

也许你的意思是这样

String theXpath = "//report-plan[@name='"+ templateName +"' and not(settings/@analysis > '')]"; 

这将选择所有<report-plan>元素具有一定的名字,没有settings/@analysis(或空一)。

+0

这不是我想要做的。更新我的问题,进一步解释 – Kelv

+0

@凯尔夫我认为这*是*你在找什么。对于每个选择的“”元素,您可以通过其“”孩子设置“分析”属性。 – Tomalak

相关问题