bufr/src/main/java/ucar/nc2/iosp/bufr/tables/WmoXmlReader.java
static void readWmoXmlTableB(InputStream ios, TableB b) throws IOException {
    org.jdom2.Document doc;
    try {
      SAXBuilder builder = new SAXBuilder();
      doc = builder.build(ios);
    } catch (JDOMException e) {
      throw new IOException(e.getMessage());
    }

    Element root = doc.getRootElement();

    String[] elems = null;
    for (Version v : Version.values()) {
      elems = v.getElemNamesB();
      List<Element> featList = root.getChildren(elems[0]);
      if (featList != null && featList.size() > 0) {
        break;
      }
    }

    // if not found using element name, assume its BUFR_WMO
    if (elems == null) {
      elems = Version.BUFR_WMO.getElemNamesB();
    }

    List<Element> featList = root.getChildren();
    for (Element elem : featList) {
      Element ce = elem.getChild(elems[1]);
      if (ce == null) continue;

      String name = Util.cleanName(elem.getChildTextNormalize(elems[1]));
      String units = cleanUnit(elem.getChildTextNormalize("BUFR_Unit"));
      int x = 0, y = 0, scale = 0, reference = 0, width = 0;

      String fxy = null;
      String s = null;
      try {
        fxy = elem.getChildTextNormalize("FXY");
        int xy = Integer.parseInt(cleanNumber(fxy));
        x = xy / 1000;
        y = xy % 1000;

      } catch (NumberFormatException e) {
        System.out.printf(" key %s name '%s' fails parsing %n", fxy, name);
      }

      try {
        s = elem.getChildTextNormalize("BUFR_Scale");
        scale = Integer.parseInt(cleanNumber(s));
      } catch (NumberFormatException e) {
        System.out.printf(" key %s name '%s' has bad scale='%s'%n", fxy, name, s);
      }

      try {
        s = elem.getChildTextNormalize("BUFR_ReferenceValue");
        reference = Integer.parseInt(cleanNumber(s));
      } catch (NumberFormatException e) {
        System.out.printf(" key %s name '%s' has bad reference='%s' %n", fxy, name, s);
      }

      try {
        s = elem.getChildTextNormalize("BUFR_DataWidth_Bits");
        width = Integer.parseInt(cleanNumber(s));
      } catch (NumberFormatException e) {
        System.out.printf(" key %s name '%s' has bad width='%s' %n", fxy, name, s);
      }

      b.addDescriptor((short) x, (short) y, scale, reference, width, name, units, null);
    }
    ios.close();
  }
static void readWmoXmlTableB(InputStream ios, TableB b) throws IOException {
    org.jdom2.Document doc;
    try {
      SAXBuilder builder = new SAXBuilder();
      doc = builder.build(ios);
    } catch (JDOMException e) {
      throw new IOException(e.getMessage());
    }

    Element root = doc.getRootElement();

    String[] elems = null;
    for (Version v : Version.values()) {
      elems = v.getElemNamesB();
      List<Element> featList = root.getChildren(elems[0]);
      if (featList != null && featList.size() > 0) {
        break;
      }
    }

    // if not found using element name, assume its BUFR_WMO
    if (elems == null) {
      elems = Version.BUFR_WMO.getElemNamesB();
    }

    List<Element> featList = root.getChildren();
    for (Element elem : featList) {
      Element ce = elem.getChild(elems[1]);
      if (ce == null) continue;

      String name = Util.cleanName(elem.getChildTextNormalize(elems[1]));
      String units = cleanUnit(elem.getChildTextNormalize("BUFR_Unit"));
      int x = 0, y = 0, scale = 0, reference = 0, width = 0;

      String fxy = null;
      String s = null;
      try {
        fxy = elem.getChildTextNormalize("FXY");
        int xy = Integer.parseInt(cleanNumber(fxy));
        x = xy / 1000;
        y = xy % 1000;

      } catch (NumberFormatException e) {
        System.out.printf(" key %s name '%s' fails parsing %n", fxy, name);
      }

      try {
        s = elem.getChildTextNormalize("BUFR_Scale");
        scale = Integer.parseInt(cleanNumber(s));
      } catch (NumberFormatException e) {
        System.out.printf(" key %s name '%s' has bad scale='%s'%n", fxy, name, s);
      }

      try {
        s = elem.getChildTextNormalize("BUFR_ReferenceValue");
        reference = Integer.parseInt(cleanNumber(s));
      } catch (NumberFormatException e) {
        System.out.printf(" key %s name '%s' has bad reference='%s' %n", fxy, name, s);
      }

      try {
        s = elem.getChildTextNormalize("BUFR_DataWidth_Bits");
        width = Integer.parseInt(cleanNumber(s));
      } catch (NumberFormatException e) {
        System.out.printf(" key %s name '%s' has bad width='%s' %n", fxy, name, s);
      }

      b.addDescriptor((short) x, (short) y, scale, reference, width, name, units, null);
    }
    ios.close();
  }
/*
14.1
<BC_TableB_BUFR14_1_0_CREX_6_1_0>
<SNo>1</SNo>
<Class>00</Class>
<FXY>000001</FXY>
<ElementName_E>Table A: entry</ElementName_E>
<ElementName_F>Table A : entr?e</ElementName_F>
<ElementName_R>??????? ?: ???????</ElementName_R>
<ElementName_S>Tabla A: elemento</ElementName_S>
<BUFR_Unit>CCITT IA5</BUFR_Unit>
<BUFR_Scale>0</BUFR_Scale>
<BUFR_ReferenceValue>0</BUFR_ReferenceValue>
<BUFR_DataWidth_Bits>24</BUFR_DataWidth_Bits>
<CREX_Unit>Character</CREX_Unit>
<CREX_Scale>0</CREX_Scale>
<CREX_DataWidth>3</CREX_DataWidth>
<Status>Operational</Status>
<NotesToTable_E>Notes: (see)#BUFR14_1_0_CREX6_1_0_Notes.doc#BC_Cl000</NotesToTable_E>
</BC_TableB_BUFR14_1_0_CREX_6_1_0>

14.2
<Exporting_BCTableB_E>
<No>2</No>
<ClassNo>00</ClassNo>
<ClassName>BUFR/CREX table entries</ClassName>
<FXY>000002</FXY>
<ElementName>Table A: data category description, line 1 </ElementName>
<BUFR_Unit>CCITT IA5 </BUFR_Unit>
<BUFR_Scale>0</BUFR_Scale>
<BUFR_ReferenceValue>0</BUFR_ReferenceValue>
<BUFR_DataWidth_Bits>256</BUFR_DataWidth_Bits>
<CREX_Unit>Character</CREX_Unit>
<CREX_Scale>0</CREX_Scale>
<CREX_DataWidth>32</CREX_DataWidth>
<Status>Operational</Status>
</Exporting_BCTableB_E>

15.1
<Exp_JointTableB_E>
<No>1</No>
<ClassNo>00</ClassNo>
<ClassName_E>BUFR/CREX table entries</ClassName_E>
<FXY>000001</FXY>
<ElementName_E>Table A: entry</ElementName_E>
<BUFR_Unit>CCITT IA5</BUFR_Unit>
<BUFR_Scale>0</BUFR_Scale>
<BUFR_ReferenceValue>0</BUFR_ReferenceValue>
<BUFR_DataWidth_Bits>24</BUFR_DataWidth_Bits>
<CREX_Unit>Character</CREX_Unit>
<CREX_Scale>0</CREX_Scale>
<CREX_DataWidth_Char>3</CREX_DataWidth_Char>
<Status>Operational</Status>
</Exp_JointTableB_E>

16.0
<Exp_BUFRCREXTableB_E>
<No>681</No>
<ClassNo>13</ClassNo>
<ClassName_E>Hydrographic and hydrological elements</ClassName_E>
<FXY>013060</FXY>
<ElementName_E>Total accumulated precipitation</ElementName_E>
<BUFR_Unit>kg m-2</BUFR_Unit>
<BUFR_Scale>1</BUFR_Scale>
<BUFR_ReferenceValue>-1</BUFR_ReferenceValue>
<BUFR_DataWidth_Bits>17</BUFR_DataWidth_Bits>
<CREX_Unit>kg m-2</CREX_Unit>
<CREX_Scale>1</CREX_Scale>
<CREX_DataWidth_Char>5</CREX_DataWidth_Char>
<Status>Operational</Status>
</Exp_BUFRCREXTableB_E>

<BUFRCREX_17_0_0_TableB_en>
<No>8</No>
<ClassNo>00</ClassNo>
<ClassName_en>BUFR/CREX table entries</ClassName_en>
<FXY>000008</FXY>
<ElementName_en>BUFR Local table version number</ElementName_en>
<Note_en>(see Note 4)</Note_en>
<BUFR_Unit>CCITT IA5</BUFR_Unit>
<BUFR_Scale>0</BUFR_Scale>
<BUFR_ReferenceValue>0</BUFR_ReferenceValue>
<BUFR_DataWidth_Bits>16</BUFR_DataWidth_Bits>
<CREX_Unit>Character</CREX_Unit>
<CREX_Scale>0</CREX_Scale>
<CREX_DataWidth_Char>2</CREX_DataWidth_Char>
<Status>Operational</Status>
</BUFRCREX_17_0_0_TableB_en>

<BUFRCREX_22_0_1_TableB_en>
<No>1018</No>
<ClassNo>21</ClassNo>
<ClassName_en>BUFR/CREX Radar data</ClassName_en>
<FXY>021073</FXY>
<ElementName_en>Satellite altimeter instrument mode</ElementName_en>
<BUFR_Unit>Flag table</BUFR_Unit>
<BUFR_Scale>0</BUFR_Scale>
<BUFR_ReferenceValue>0</BUFR_ReferenceValue>
<BUFR_DataWidth_Bits>9</BUFR_DataWidth_Bits>
<CREX_Unit>Flag table</CREX_Unit>
<CREX_Scale>0</CREX_Scale>
<CREX_DataWidth_Char>3</CREX_DataWidth_Char>
<Status>Operational</Status>
</BUFRCREX_22_0_1_TableB_en>