2015-04-30 19 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> 

На данный момент мой код ввода такое же значение, как для отчеты называются 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

Что случилось с вашей текущей XPath? – har07

+1

Выберите только _что точно, если атрибут 'анализ' пуст? –

+0

Выберите этот атрибут анализа только в этом элементе плана отчета. Есть несколько элементов плана отчета, некоторые из которых имеют значения, а другие пустые, поэтому я выбираю только те, которые пусты. Обновлен, чтобы показать связанный код. – Kelv

ответ

3

Хорошо, я думаю, что вижу, что вы собираетесь здесь. Вы хотите использовать XPath, чтобы предоставить вам узлы @analysis, которые существуют и пустые, так что вы можете заполнить их некоторым настроенным значением.

String theXpath = "//report-plan[@name='" + templateName + "']/settings/@analysis[.='']"; 

отредактирован ADD:

Теперь, имейте в виду, что это будет выбрать все @analysis узлы для имени шаблона. Когда вы выполняете цикл второго уровня for, вы меняете ВСЕ из них. На следующем CSV, который называется «generic», он не найдет узлов, которые нужно изменить.

Заменить:

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

@ Kelv Я думаю, что это * *, что вы ищете. Для каждого выбранного элемента '' вы можете использовать его '' child, чтобы перейти к атрибуту 'анализ'. – Tomalak

Смежные вопросы