コード例 #1
0
        /// <summary>
        ///   Convert BCP 47 tag to a valid Unicode locale identifier
        /// </summary>
        string TransformFromBcp47()
        {
            // 1. Canonicalize the language tag (afterwards, there will be no extlang subtag)

            // 2. Replace the BCP 47 primary language subtag "und" with "root" if no script, region,
            //    or variant subtags are present
            if (Language == "und" && Script == "" && Region == "" && Variants.Count() == 0)
            {
                Language = "root";
            }

            // 3. If the BCP 47 primary language subtag matches the type attribute of a languageAlias
            //    element in Supplemental Data, replace the language subtag with the replacement value.
            // 3.1 If there are additional subtags in the replacement value, add them to the result, but only
            //     if there is no corresponding subtag already in the tag.
            var languageAlias = Cldr.Instance
                                .GetDocuments("common/supplemental/supplementalMetadata.xml")
                                .FirstElementOrDefault($"supplementalData/metadata/alias/languageAlias[@type='{Language}']");

            if (languageAlias != null)
            {
                var replacement = LocaleIdentifier.ParseBcp47(languageAlias.GetAttribute("replacement", ""));
                Language = replacement.Language;
                if (Script == "")
                {
                    Script = replacement.Script;
                }
                if (Region == "")
                {
                    Region = replacement.Region;
                }
            }

            // 4. If the BCP 47 region subtag matches the type attribute of a territoryAlias
            //    element in Supplemental Data, replace the language subtag with the replacement value, as follows:
            var territoryAlias = Cldr.Instance
                                 .GetDocuments("common/supplemental/supplementalMetadata.xml")
                                 .FirstElementOrDefault($"supplementalData/metadata/alias/territoryAlias[@type='{Region}']");

            if (territoryAlias != null)
            {
                var replacements = territoryAlias.GetAttribute("replacement", "").Split(' ');
                //    4.1 If there is a single territory in the replacement, use it.
                var replacementValue = replacements[0];
                //    4.2 If there are multiple territories:
                //        4.2.1 Look up the most likely territory for the base language code(and script, if there is one).
                //        4.2.2 If that likely territory is in the list, use it.
                //        4.2.3 Otherwise, use the first territory in the list.
                if (replacements.Length > 1)
                {
                    var best = Cldr.Instance
                               .GetDocuments("common/supplemental/likelySubtags.xml")
                               .FirstElementOrDefault($"supplementalData/likelySubtags/likelySubtag[@from='{Language}']");
                    if (best != null)
                    {
                        var to = LocaleIdentifier.ParseBcp47(best.GetAttribute("to", ""));
                        if (replacements.Contains(to.Region))
                        {
                            replacementValue = to.Region;
                        }
                    }
                }
                Region = replacementValue;
            }

            // Verify that the subtags are defined.
            // TODO: Need StringRanges, see https://github.com/richardschneider/net-cldr/issues/2
            if (Language != "" && !Cldr.Instance.IsLanguageDefined(Language))
            {
                return($"Language '{Language}' is not defined.");
            }
            if (Script != "" && !Cldr.Instance.IsScriptDefined(Script))
            {
                return($"Script '{Script}' is not defined.");
            }
            if (Region != "" && !Cldr.Instance.IsRegionDefined(Region))
            {
                return($"Region '{Region}' is not defined.");
            }
            foreach (var variant in Variants)
            {
                if (!Cldr.Instance.IsVariantDefined(variant))
                {
                    return($"Language variant '{variant}' is not defined.");
                }
            }

            // TODO: U extensions
            // TODO: T extensions

            return(null);
        }