grib/src/main/java/ucar/nc2/grib/grib2/table/WmoTemplateTables.java
private void readXml(Version version) throws IOException {
    try (InputStream ios = WmoTemplateTables.class.getResourceAsStream(version.getResourceName())) {
      if (ios == null) {
        throw new IOException("cant open TemplateTable %s " + version.getResourceName());
      }

      org.jdom2.Document doc;
      try {
        SAXBuilder builder = new SAXBuilder();
        doc = builder.build(ios);
      } catch (JDOMException e) {
        throw new IOException(e.getMessage());
      }

      Map<String, TemplateTable> map = new HashMap<>();
      String[] elems = version.getElemNames();
      assert elems != null;
      assert elems.length > 3;

      Element root = doc.getRootElement();
      List<Element> featList = root.getChildren(elems[0]); // 0 = main element
      for (Element elem : featList) {
        String desc = elem.getChildTextNormalize(elems[1]); // 1 = title
        String octet = elem.getChildTextNormalize("OctetNo");
        String content = elem.getChildTextNormalize(elems[3]); // 3 = content
        String status = elem.getChildTextNormalize("Status");
        String note = elem.getChildTextNormalize(elems[2]); // 2 == note

        TemplateTable template = map.computeIfAbsent(desc, name -> new TemplateTable(name));
        template.add(octet, content, status, note);
      }
      ios.close();

      List<TemplateTable> tlist = new ArrayList<>(map.values());
      for (TemplateTable t : tlist) {
        if (t.m1 == 3) {
          t.add(1, 4, "GDS length");
          t.add(5, 1, "Section");
          t.add(6, 1, "Source of Grid Definition (see code table 3.0)");
          t.add(7, 4, "Number of data points");
          t.add(11, 1, "Number of octects for optional list of numbers");
          t.add(12, 1, "Interpretation of list of numbers");
          t.add(13, 2, "Grid Definition Template Number");

        } else if (t.m1 == 4) {
          t.add(1, 4, "PDS length");
          t.add(5, 1, "Section");
          t.add(6, 2, "Number of coordinates values after Template");
          t.add(8, 2, "Product Definition Template Number");
        }
        Collections.sort(t.flds);
      }

      this.templateTables = map.values().stream().sorted().collect(ImmutableList.toImmutableList());
      ImmutableMap.Builder<String, TemplateTable> builder = ImmutableMap.builder();
      map.values().forEach(t -> builder.put(t.getId(), t));
      this.templateMap = builder.build();
    }
  }
private void readXml(Version version) throws IOException {
    try (InputStream ios = WmoTemplateTables.class.getResourceAsStream(version.getResourceName())) {
      if (ios == null) {
        throw new IOException("cant open TemplateTable %s " + version.getResourceName());
      }

      org.jdom2.Document doc;
      try {
        SAXBuilder builder = new SAXBuilder();
        doc = builder.build(ios);
      } catch (JDOMException e) {
        throw new IOException(e.getMessage());
      }

      Map<String, TemplateTable> map = new HashMap<>();
      String[] elems = version.getElemNames();
      assert elems != null;
      assert elems.length > 3;

      Element root = doc.getRootElement();
      List<Element> featList = root.getChildren(elems[0]); // 0 = main element
      for (Element elem : featList) {
        String desc = elem.getChildTextNormalize(elems[1]); // 1 = title
        String octet = elem.getChildTextNormalize("OctetNo");
        String content = elem.getChildTextNormalize(elems[3]); // 3 = content
        String status = elem.getChildTextNormalize("Status");
        String note = elem.getChildTextNormalize(elems[2]); // 2 == note

        TemplateTable template = map.computeIfAbsent(desc, name -> new TemplateTable(name));
        template.add(octet, content, status, note);
      }
      ios.close();

      List<TemplateTable> tlist = new ArrayList<>(map.values());
      for (TemplateTable t : tlist) {
        if (t.m1 == 3) {
          t.add(1, 4, "GDS length");
          t.add(5, 1, "Section");
          t.add(6, 1, "Source of Grid Definition (see code table 3.0)");
          t.add(7, 4, "Number of data points");
          t.add(11, 1, "Number of octects for optional list of numbers");
          t.add(12, 1, "Interpretation of list of numbers");
          t.add(13, 2, "Grid Definition Template Number");

        } else if (t.m1 == 4) {
          t.add(1, 4, "PDS length");
          t.add(5, 1, "Section");
          t.add(6, 2, "Number of coordinates values after Template");
          t.add(8, 2, "Product Definition Template Number");
        }
        Collections.sort(t.flds);
      }

      this.templateTables = map.values().stream().sorted().collect(ImmutableList.toImmutableList());
      ImmutableMap.Builder<String, TemplateTable> builder = ImmutableMap.builder();
      map.values().forEach(t -> builder.put(t.getId(), t));
      this.templateMap = builder.build();
    }
  }
/*
<GRIB2_22_0_0_Template_en>
<No>1451</No>
<Title_en>Product definition template 4.55 - spatio-temporal changing tiles at a horizontal level or horizontal layer at a point in time</Title_en>
<OctetNo>35</OctetNo>
<Contents_en>Type of second fixed surface</Contents_en>
<Note_en>(see Code table 4.5)</Note_en>
<Status>Operational</Status>
</GRIB2_22_0_0_Template_en>