【问题标题】:How to Remove newline characters from List<String>如何从 List<String> 中删除换行符
【发布时间】:2015-08-20 03:19:14
【问题描述】:

我有一个方法可以从 XML 文件中返回一个 Map。我已经将该映射转换为将键和值分开到列表中。

但是我注意到值列表中有换行符。如何去掉换行符并用空格替换它们或将它们留空。

代码:

@Test
public void testGetXMLModelData() throws Exception {
    File f = new File("xmlDir/example.xml");
    Model m = getXMLModelData(f);

    logger.debug("Models Keys: "+m.getInputs());
    logger.debug("Models Values: "+m.getValues());
}

public Model getXMLModelData(File f) throws Exception { 

    Model model = new Model();

    Map<String,String> map = p(f);
    List<String> listKeys = new ArrayList<String>(map.keySet());
    List<String> listValues = new ArrayList<String>(map.values());

    model.setInputs(listKeys);
    model.setValues(listValues); 

    return model;
}


public Map<String, String> p(File file) throws Exception {

    Map<String, String> map = new HashMap<String,String>();
    XMLStreamReader xr = XMLInputFactory.newInstance().createXMLStreamReader(new FileInputStream(file));

    while(xr.hasNext()) {

        int e = xr.next();
        if (e == XMLStreamReader.START_ELEMENT) {
            String name = xr.getLocalName();
            xr.next();
            String value = null;
            try {
                value = xr.getText();
            } catch (IllegalStateException exep) {
                exep.printStackTrace();
            }
            map.put(name, value);
        } 
    }
    return map;
}

输出:

2015-08-19 20:13:52,327 : Models Keys: [IRS1095A, MonthlyPlanPremiumAmtPP, WagesSalariesAndTipsAmt, MonthlyAdvancedPTCAmtPP, MonthCdPP, ReturnData, IndividualReturnFilingStatusCd, PrimaryResidentStatesInfoGrpPP, MonthlyPTCInformationGrpPP, IRS1040, ResidentStateInfoPP, SelfSelectPINGrp, MonthlyPremiumSLCSPAmtPP, Filer, ResidentStateAbbreviationCdPP, PrimaryBirthDt, Return, ReturnHeader, TotalExemptionsCnt, AdjustedGrossIncomeAmt, PrimarySSN]
2015-08-19 20:13:52,328 : Models Values: [
      , 136, 22000, 125, SEPTEMBER, 
    , 1, 
        , 
        , 
      , 
          , 
      , 250, 
      , CA, 1970-01-01, 
  , 
    , 1, 22000, 555-11-2222]

任何帮助或帮助将不胜感激。提前致谢

编辑:

XML 文件

<Return xmlns="http://www.irs.gov/efile">
  <ReturnData>
    <IRS1095A uuid="a77f40a2-af31-4404-a27d-4c1eaad730c2">
      <MonthlyPTCInformationGrpPP uuid="69dc9dd5-5415-4ee4-a199-19b2dbb701be">
        <MonthlyPlanPremiumAmtPP>136</MonthlyPlanPremiumAmtPP>
        <MonthlyAdvancedPTCAmtPP>125</MonthlyAdvancedPTCAmtPP>
        <MonthCdPP>SEPTEMBER</MonthCdPP>
        <MonthlyPremiumSLCSPAmtPP>250</MonthlyPremiumSLCSPAmtPP>
      </MonthlyPTCInformationGrpPP>
    </IRS1095A>
    <IRS1040>
      <IndividualReturnFilingStatusCd>1</IndividualReturnFilingStatusCd>
      <WagesSalariesAndTipsAmt>22000</WagesSalariesAndTipsAmt>
      <TotalExemptionsCnt>1</TotalExemptionsCnt>
      <AdjustedGrossIncomeAmt>22000</AdjustedGrossIncomeAmt>
    </IRS1040>
  </ReturnData>
  <ReturnHeader>
    <SelfSelectPINGrp>
      <PrimaryBirthDt>1970-01-01</PrimaryBirthDt>
    </SelfSelectPINGrp>
    <Filer>
      <PrimarySSN>555-11-2222</PrimarySSN>
      <PrimaryResidentStatesInfoGrpPP>
        <ResidentStateInfoPP uuid="a77f40a2-af31-4404-a27d-4c1eaad730c2">
          <ResidentStateAbbreviationCdPP>CA</ResidentStateAbbreviationCdPP>
        </ResidentStateInfoPP>
      </PrimaryResidentStatesInfoGrpPP>
    </Filer>
  </ReturnHeader>
</Return>

【问题讨论】:

  • 也显示 XML 文件。
  • 我已经发布了 XML 文件

标签: java regex xml data-structures stax


【解决方案1】:

设置value = xr.getText().trim()。这将从值的开头和结尾删除无关字符。

为了防止添加该值,请将map.put(name, value) 包装为if (value != null &amp;&amp; !value.isEmpty())

【讨论】:

  • 我怎么能只得到值而没有空值,看起来我正在做的解析是让每个节点甚至没有值的根节点。
  • 将 map.put() 命令包装在 if 语句中,在其中检查非空值。我会把它添加到我的答案中。
  • 那将非常有帮助,我期待您的回答。谢谢。
  • 它在技术上不是答案的一部分,所以我会把它放在这里,但你应该将与值相关的所有内容移到 try 块中。您可以将值声明和赋值合并为一个步骤,并从我的答案附录中删除空检查。
【解决方案2】:

您的代码正在提取元素名称和紧跟在开始元素之后的文本,忽略任何跟在结束元素之后的文本。

所以,它收集:

Return = <newline><space><space>
ReturnData = <newline><space><space><space><space>
IRS1095A = <newline><space><space><space><space><space><space>
MonthlyPTCInformationGrpPP = <newline><space><space><space><space><space><space><space><space>
MonthlyPlanPremiumAmtPP = 136
...

然后将它们添加到 HashMap 中,它会以随机顺序对键/值对进行打乱,从而很难看到发生了什么。

更新

我不会为你编写代码,但如果你想要“价值元素”,那么你需要:

  1. 看到时记住起始元素
  2. 收集任何文本,与已收集的其他文本连接,例如当你看到
  3. 当看到一个起始元素并记住一个起始元素时,验证文本是否为空或全是空格,然后丢弃文本
  4. 看到结束元素时:
    1. 如果记住了起始元素,则将元素名称/文本添加到结果中,然后忘记起始元素并丢弃文本。注意:如果相同的元素名称可以出现多次,请勿使用 map。
    2. 如果起始元素没有被记住(被遗忘),验证文本是否为空或全是空格,然后丢弃文本

这将只收集叶子元素,忽略任何“布局”。

代码完全如上所写

嗯,我确实添加了缺失的资源清理。

Map<String, String> map = new HashMap<>();
try (FileInputStream in = new FileInputStream(file)) {
    XMLStreamReader xr = XMLInputFactory.newInstance().createXMLStreamReader(in);
    try (
        String elementName = null;
        StringBuilder textBuf = new StringBuilder();
        while (xr.hasNext()) {
            switch (xr.next()) {
                case XMLStreamConstants.START_ELEMENT:
                    // 3. When seeing a start element and a start element is remembered
                    if (elementName != null) {
                        // verify text is empty or all whitespace
                        if (! textBuf.toString().trim().isEmpty())
                            throw new IllegalArgumentException("Found text mixed with elements");
                        // then discard text
                        textBuf.setLength(0);
                    }
                    // 1. Remember start element when seen
                    elementName = xr.getLocalName();
                    break;
                case XMLStreamConstants.CHARACTERS:
                case XMLStreamConstants.CDATA:
                case XMLStreamConstants.SPACE:
                    // 2. Collect any text
                    textBuf.append(xr.getText());
                    break;
                case XMLStreamConstants.END_ELEMENT: // 4. When seeing an end element
                    if (elementName != null) { // 1. if start element is remembered
                        // add elementName/text to result
                        map.put(elementName, textBuf.toString());
                        // then forget start element
                        elementName = null;
                        // and discard text
                        textBuf.setLength(0);
                    } else { // 2. if start element is not remembered (was forgotton)
                        // verify text is empty or all whitespace
                        if (! textBuf.toString().trim().isEmpty())
                            throw new IllegalArgumentException("Found text mixed with elements");
                        // then discard text
                        textBuf.setLength(0);
                    }
                    break;
                default:
                    // ignore
            } 
        }
    } finally {
        xr.close();
    }
}
return map;

【讨论】:

  • 是的,你完全正确。我不知道该怎么说,但你说了。我如何修改它以仅收集具有值的元素?我已经尝试了大约 2 天了...没有运气...问题是我不确定如何提出问题,但您似乎很好理解
  • 有值的元素?如果PrimarySSN 是一个空字符串怎么办?你还想要吗?您知道要读取的 XML,还是应该处理 任何 XML 文件?
  • 没错!你在读我的心!!它应该处理任何 XML,因此事先不知道文档结构!
  • 我在执行此操作时遇到了一些麻烦,我对这一切都很陌生。一个例子将不胜感激。
猜你喜欢
  • 2014-07-20
  • 2019-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多