-
至尊宝的传说
Java Stream API 可以提供帮助 String raw ="name1|value1\n" + "name2|value2"; String template = "<data attribute=\"%s\">%s</data>"; String output = Arrays.stream(raw.split("\n")) .map(rawPair -> rawPair.split("\\|")) .map(pair -> String.format(template, pair[0], pair[1])) .collect(Collectors.joining("\n"));将输出<data attribute="name1">value1</data><data attribute="name2">value2</data>但拥有特定的业务逻辑需要更多的动作。首先获取国家代码,然后在流处理上装饰您的属性名称 BiFunction<String, String, String> decorate = (String name, String code) -> { if ("state".equals(name)) { return name + code; } else { return name; } }; Function<String, String> countryCode = (String source) -> { String head = "country|"; int start = source.indexOf(head) + head.length(); return source.substring(start, start + 2); }; String code = countryCode.apply(raw); ... .map(pair -> String.format(template, decorate.apply(pair[0], code), pair[1])) ...
-
白板的微信
有了新的要求原始文件很大原始文件的国家/地区代码位于州旁边一份一份地读取文件。还需要按照原始源中出现的顺序输出转换后的条目。你应该识别状态并保留它,尚未生成下一个条目识别后续国家,更新保存的状态并释放州和国家条目所以在这里我为这个角色使用了某种浅缓冲区 String raw = "name|value1\n" + "state|some-state1\n" + "country|fr-fra\n" + "name|value2\n" + "state|some-state2\n" + "country|en-us\n"; class ShallowBuffer { private String stateKey = "state"; private String countryKey = "country"; private String[] statePairWaitingForCountryCode = null; private List<String[]> pump(String[] pair) { if (stateKey.equals(pair[0])) { statePairWaitingForCountryCode = pair; return Collections.emptyList(); } if (countryKey.equals(pair[0])) { statePairWaitingForCountryCode[0] = statePairWaitingForCountryCode[0] + pair[1].substring(0, 2); String[] stateRelease = statePairWaitingForCountryCode; statePairWaitingForCountryCode = null; return Arrays.asList(stateRelease, pair); } return Collections.singletonList(pair); } } ShallowBuffer patience = new ShallowBuffer(); String template = "<data attribute=\"%s\">%s</data>"; String output = Arrays.stream(raw.split("\n")) .map(rawPair -> rawPair.split("\\|")) .map(patience::pump) .flatMap(Collection::stream) .map(pair -> String.format(template, pair[0], pair[1])) .collect(Collectors.joining("\n"));这将输出 <data attribute="name">value1</data> <data attribute="statefr">some-state1</data> <data attribute="country">fr-fra</data> <data attribute="name">value2</data> <data attribute="stateen">some-state2</data> <data attribute="country">en-us</data>浅缓冲区是可变的,因此您不能在流链中使用并行方法。这也意味着将其标记为可访问范围之外将需要同步工作。并且您仍然需要将国家/地区代码的第一个字母大写)
-
aluckdog
运行以下 XSLT 3.0 样式表:<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" expand-text="yes" xmlns:f="f"><xsl:template name="xsl:initial-template"> <root> <xsl:iterate select="unparsed-text-lines('input.txt')"> <xsl:param name="prev-parts" select="()"/> <xsl:on-completion> <attribute name="{$prev-parts[1]}">{$prev-parts[2]}</attribute> </xsl:on-completion> <xsl:variable name="parts" select="tokenize(., '\|')"/> <xsl:choose> <xsl:when test="$parts[1] = 'country'"> <attribute name="{f:titleCase($prev-parts[1])}{f:titleCase(substring-before($parts[2], '-')}">{$prev-parts[2]}</attribute> </xsl:when> <xsl:otherwise> <attribute name="{$prev-parts[1]}>{$prev-parts[2]}</attribute> </xsl:otherwise> </xsl:choose> <xsl:next-iteration> <xsl:with-param name="prev-parts" select="$parts"/> </xsl:next-iteration> </xsl:iterate> </root></xsl:template><xsl:function name="f:titleCase"> <xsl:param name="in"/> <xsl:sequence select="upper-case(substring($in, 1, 1))||substring($in, 2)"/></xsl:function> </xsl:transform>请注意,与此处介绍的其他解决方案不同,此解决方案始终会生成格式良好的 XML 输出。