diff --git a/indra/llui/lltransutil.cpp b/indra/llui/lltransutil.cpp
index 3b7e737dea57af14a38fd94f365380daa71fe2ec..80d079cbc8ca3c0781976841fc79172355c9f007 100644
--- a/indra/llui/lltransutil.cpp
+++ b/indra/llui/lltransutil.cpp
@@ -35,21 +35,13 @@
 
 bool LLTransUtil::parseStrings(const std::string& xml_filename, const std::set<std::string>& default_args)
 {
-	// LLUICtrlFactory::getLayeredXMLNode() just calls
-	// gDirUtilp->findSkinnedFilenames(constraint=LLDir::CURRENT_SKIN) and
-	// then passes the resulting paths to LLXMLNode::getLayeredXMLNode().
-	// Bypass that and call LLXMLNode::getLayeredXMLNode() directly: we want
-	// constraint=LLDir::ALL_SKINS.
-	std::vector<std::string> paths =
-		gDirUtilp->findSkinnedFilenames(LLDir::XUI, xml_filename, LLDir::ALL_SKINS);
-	if (paths.empty())
-	{
-		// xml_filename not found at all in any skin -- check whether entire
-		// path was passed (but I hope we no longer have callers who do that)
-		paths.push_back(xml_filename);
-	}
 	LLXMLNodePtr root;
-	bool success = LLXMLNode::getLayeredXMLNode(root, paths);
+	// Pass LLDir::ALL_SKINS to load a composite of all the individual string
+	// definitions in the default skin and the current skin. This means an
+	// individual skin can provide an xml_filename that overrides only a
+	// subset of the available string definitions; any string definition not
+	// overridden by that skin will be sought in the default skin.
+	bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root, LLDir::ALL_SKINS);
 	if (!success)
 	{
 		llerrs << "Couldn't load string table " << xml_filename << llendl;
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index 2b317b46e3206d736f01cb4446755589b985fc2c..f7307cd0764114a823800c61fbddb7a26472464d 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -151,11 +151,12 @@ static LLFastTimer::DeclareTimer FTM_XML_PARSE("XML Reading/Parsing");
 //-----------------------------------------------------------------------------
 // getLayeredXMLNode()
 //-----------------------------------------------------------------------------
-bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root)
+bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root,
+                                        LLDir::ESkinConstraint constraint)
 {
 	LLFastTimer timer(FTM_XML_PARSE);
 	std::vector<std::string> paths =
-		gDirUtilp->findSkinnedFilenames(LLDir::XUI, xui_filename);
+		gDirUtilp->findSkinnedFilenames(LLDir::XUI, xui_filename, constraint);
 
 	if (paths.empty())
 	{
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 56e5f3eb7b609ed31c0103c7ea59e9183fd9790f..1acfd24112d607310361ac044c9c74588c2c5284 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -31,6 +31,7 @@
 #include "llinitparam.h"
 #include "llregistry.h"
 #include "llxuiparser.h"
+#include "lldir.h"
 
 class LLView;
 
@@ -212,7 +213,8 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 
 	static void createChildren(LLView* viewp, LLXMLNodePtr node, const widget_registry_t&, LLXMLNodePtr output_node = NULL);
 
-	static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root);
+	static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root,
+								  LLDir::ESkinConstraint constraint=LLDir::CURRENT_SKIN);
 
 private:
 	//NOTE: both friend declarations are necessary to keep both gcc and msvc happy