3 回答

TA貢獻1789條經(jīng)驗 獲得超10個贊
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>
但擁有特定的業(yè)務(wù)邏輯需要更多的動作。首先獲取國家代碼,然后在流處理上裝飾您的屬性名稱
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]))
...

TA貢獻1883條經(jīng)驗 獲得超3個贊
有了新的要求
原始文件很大
原始文件的國家/地區(qū)代碼位于州旁邊
一份一份地讀取文件。
還需要按照原始源中出現(xiàn)的順序輸出轉(zhuǎn)換后的條目。
你應(yīng)該
識別狀態(tài)并保留它,尚未生成下一個條目
識別后續(xù)國家,更新保存的狀態(tài)并釋放州和國家條目
所以在這里我為這個角色使用了某種淺緩沖區(qū)
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>
淺緩沖區(qū)是可變的,因此您不能在流鏈中使用并行方法。這也意味著將其標(biāo)記為可訪問范圍之外將需要同步工作。并且您仍然需要將國家/地區(qū)代碼的第一個字母大寫)

TA貢獻1847條經(jīng)驗 獲得超7個贊
運行以下 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 輸出。
添加回答
舉報