将原始数据转换为自定义的xml

时间:2019-10-03 06:23:31

标签: java xml

我想使用Java将原始文件转换为以下格式-

原始输入:

state | abc
country | FR-FRA

输出:

<data attr ="StateFr">abc</data>
<data attr ="country">FR-FRA</data>

州属性应附加上面显示的国家/地区代码。有人可以帮我吗?

3 个答案:

答案 0 :(得分:1)

Java Stream API可以帮助

select js ->> 'Date' as Date, js ->> 'TableName' as TableName, js ->> 'Count' as Count 
  from
  (
    select json_array_elements(jsondata) as js
      from sample
  ) q

将输出

    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>

答案 1 :(得分:0)

有新要求

  1. 原始文件很大
  2. 原始文件的国家/地区代码紧跟州/州
  3. 一一读取文件。
  4. 还需要以与原始源中出现的顺序相同的顺序输出转换后的条目。

您应该

  1. 识别状态并保留它,尚未生成下一个条目
  2. 识别后续的国家,更新保留的状态,并释放状态 contry 条目

所以在这里,我为此角色采用了浅层缓冲区

    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>

浅缓冲区是可变的,因此您不能在流链中使用 parallel 方法。 这也意味着标记可访问范围之外的内容将需要同步工作。 而且您仍然需要使用国家/地区代码的首字母大写)

答案 2 :(得分:0)

运行以下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输出。 (我们在StackOverflow上看到了很多问题,人们收到了错误生成的所谓XML,因为它忽略了转义特殊字符的问题。)