From 22404a60b1da9953f5832248f9770aa9536b9c7f Mon Sep 17 00:00:00 2001 From: flowAlexS Date: Tue, 12 Aug 2025 17:18:18 +0300 Subject: [PATCH 1/3] Updated the plugin to add Prefix Namespaces --- .../BatchTasks/ExportBatchTask.cs | 3 ++ .../Extensions/XMLDocumentExtensions.cs | 30 +++++++++++++++++++ .../Multilingual.XML.FileType.csproj | 4 +-- .../Properties/AssemblyInfo.cs | 2 +- .../Services/BilingualParser.cs | 1 + .../Services/BilingualWriter.cs | 4 ++- .../Services/DefaultNamespaceHelper.cs | 20 ++++++++++++- .../Services/XMLFileSniffer.cs | 5 +++- .../pluginpackage.manifest.xml | 2 +- 9 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 Multilingual XML FileType/Multilingual.XML.FileType/Extensions/XMLDocumentExtensions.cs diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/BatchTasks/ExportBatchTask.cs b/Multilingual XML FileType/Multilingual.XML.FileType/BatchTasks/ExportBatchTask.cs index 417644a6f3..25c21ca42b 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/BatchTasks/ExportBatchTask.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/BatchTasks/ExportBatchTask.cs @@ -9,6 +9,7 @@ using System.Xml; using Multilingual.XML.FileType.BatchTasks.Pages; using Multilingual.XML.FileType.BatchTasks.Settings; +using Multilingual.XML.FileType.Extensions; using Multilingual.XML.FileType.FileType.Processors; using Multilingual.XML.FileType.FileType.Settings; using Multilingual.XML.FileType.Models; @@ -220,6 +221,8 @@ public override void TaskComplete() outputDocument.Load(outputXmlReader); var nsmgr = new XmlNamespaceManager(outputDocument.NameTable); + outputDocument.AddAllNamespaces(nsmgr); + var namespaceUri = _defaultNamespaceHelper.GetXmlNameSpaceUri( multilingualFileInfo.MultilingualFilePath, multilingualFileInfo.FileEncoding); if (!string.IsNullOrEmpty(namespaceUri)) diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Extensions/XMLDocumentExtensions.cs b/Multilingual XML FileType/Multilingual.XML.FileType/Extensions/XMLDocumentExtensions.cs new file mode 100644 index 0000000000..c2e73b8cf6 --- /dev/null +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Extensions/XMLDocumentExtensions.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml; + +namespace Multilingual.XML.FileType.Extensions +{ + public static class XMLDocumentExtensions + { + public static void AddAllNamespaces(this XmlDocument doc, XmlNamespaceManager nsmgr) + { + var root = doc.DocumentElement; + if (root == null) return; + + foreach (XmlAttribute attr in root.Attributes) + { + if (attr.Prefix == "xmlns") + { + nsmgr.AddNamespace(attr.LocalName, attr.Value); + } + else if (attr.Name == "xmlns") + { + nsmgr.AddNamespace(string.Empty, attr.Value); // default namespace + } + } + } + } +} diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Multilingual.XML.FileType.csproj b/Multilingual XML FileType/Multilingual.XML.FileType/Multilingual.XML.FileType.csproj index 6214a14156..7a05000558 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/Multilingual.XML.FileType.csproj +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Multilingual.XML.FileType.csproj @@ -1,9 +1,9 @@  net48 - C:\Program Files (x86)\Trados\Trados Studio\Studio18beta + C:\Program Files (x86)\Trados\Trados Studio\Studio18 false - $(AppData)\Trados\Trados Studio\18beta\Plugins + $(AppData)\Trados\Trados Studio\18\Plugins true true true diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Properties/AssemblyInfo.cs b/Multilingual XML FileType/Multilingual.XML.FileType/Properties/AssemblyInfo.cs index 140df90cd1..b6186b595c 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/Properties/AssemblyInfo.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Properties/AssemblyInfo.cs @@ -28,4 +28,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("3.0.0.0")] -[assembly: AssemblyFileVersion("3.1.1.0")] +[assembly: AssemblyFileVersion("3.1.2.0")] diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualParser.cs b/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualParser.cs index 36c7620559..c751f65ee4 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualParser.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualParser.cs @@ -177,6 +177,7 @@ public bool ParseNext() _document.Load(_xmlReader); _nsmgr = new XmlNamespaceManager(_document.NameTable); + _document.AddAllNamespaces(_nsmgr); UpdateLanguageMappingSettings(_nsmgr); diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualWriter.cs b/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualWriter.cs index cd87b4fdfd..4ed26ca833 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualWriter.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualWriter.cs @@ -12,6 +12,7 @@ using Sdl.FileTypeSupport.Framework.BilingualApi; using Sdl.FileTypeSupport.Framework.NativeApi; using Sdl.FileTypeSupport.Framework.IntegrationApi; +using Multilingual.XML.FileType.Extensions; namespace Multilingual.XML.FileType.Services { @@ -167,8 +168,9 @@ public void SetFileProperties(IFileProperties fileInfo) _targetDocument.Load(_xmlReader); _nsmgr = new XmlNamespaceManager(_targetDocument.NameTable); + _targetDocument.AddAllNamespaces(_nsmgr); - if (_originalFileProperties.FileSnifferInfo != null && _originalFileProperties.FileSnifferInfo.MetaDataContainsKey(Constants.DefaultNamespace)) + if (_originalFileProperties.FileSnifferInfo != null && _originalFileProperties.FileSnifferInfo.MetaDataContainsKey(Constants.DefaultNamespace)) { var namespaceUri = _originalFileProperties.FileSnifferInfo.GetMetaData(Constants.DefaultNamespace); if (!string.IsNullOrEmpty(namespaceUri)) diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Services/DefaultNamespaceHelper.cs b/Multilingual XML FileType/Multilingual.XML.FileType/Services/DefaultNamespaceHelper.cs index d1e2c89117..88219689bc 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/Services/DefaultNamespaceHelper.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Services/DefaultNamespaceHelper.cs @@ -16,7 +16,25 @@ public DefaultNamespaceHelper(XmlReaderFactory xmlReaderFactory) _xmlReaderFactory = xmlReaderFactory; } - public string GetXmlNameSpaceUri(string filePath, Encoding encoding) + public void AddAllNamespacesFromDocument(XmlDocument doc, XmlNamespaceManager nsmgr) + { + var root = doc.DocumentElement; + if (root == null) return; + + foreach (XmlAttribute attr in root.Attributes) + { + if (attr.Prefix == "xmlns") + { + nsmgr.AddNamespace(attr.LocalName, attr.Value); + } + else if (attr.Name == "xmlns") + { + nsmgr.AddNamespace(string.Empty, attr.Value); // default namespace + } + } + } + + public string GetXmlNameSpaceUri(string filePath, Encoding encoding) { string namespaceUri; using (var fs = new FileStream(filePath, FileMode.Open)) diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Services/XMLFileSniffer.cs b/Multilingual XML FileType/Multilingual.XML.FileType/Services/XMLFileSniffer.cs index 52b3d23a07..3fc2300709 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/Services/XMLFileSniffer.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Services/XMLFileSniffer.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Text; using System.Xml; +using Multilingual.XML.FileType.Extensions; using Multilingual.XML.FileType.FileType.Settings; using Sdl.Core.Globalization; using Sdl.Core.Settings; @@ -86,7 +87,9 @@ private bool IsFileSupported(string filePath, string namespaceUri, Encoding enco document.Load(reader); var nsmgr = new XmlNamespaceManager(document.NameTable); - if (!string.IsNullOrEmpty(namespaceUri)) + document.AddAllNamespaces(nsmgr); + + if (!string.IsNullOrEmpty(namespaceUri)) { var defaultNameSpace = new XmlNameSpace { Name = Constants.DefaultNamespace, Value = namespaceUri }; _defaultNamespaceHelper.AddXmlNameSpacesFromDocument(nsmgr, document, defaultNameSpace); diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/pluginpackage.manifest.xml b/Multilingual XML FileType/Multilingual.XML.FileType/pluginpackage.manifest.xml index 8bf95e3e93..7827d9b321 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/pluginpackage.manifest.xml +++ b/Multilingual XML FileType/Multilingual.XML.FileType/pluginpackage.manifest.xml @@ -1,7 +1,7 @@ Multilingual XML FileType - 3.1.1.0 + 3.1.2.0 Multilingual XML File Type Trados AppStore Team From f929a0751e49a58456439e5fe2f8225eba8d18ae Mon Sep 17 00:00:00 2001 From: flowAlexS Date: Tue, 12 Aug 2025 17:38:04 +0300 Subject: [PATCH 2/3] Updated the plugin to handle language paths that start with predicates --- .../BatchTasks/ExportBatchTask.cs | 4 ++-- .../Extensions/XMLDocumentExtensions.cs | 11 +++++++++++ .../Services/BilingualParser.cs | 4 ++-- .../Services/BilingualWriter.cs | 2 +- .../Services/XMLFileSniffer.cs | 15 ++++++++++----- .../Services/XmlNodeService.cs | 7 ++++--- 6 files changed, 30 insertions(+), 13 deletions(-) diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/BatchTasks/ExportBatchTask.cs b/Multilingual XML FileType/Multilingual.XML.FileType/BatchTasks/ExportBatchTask.cs index 25c21ca42b..dbcb93395d 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/BatchTasks/ExportBatchTask.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/BatchTasks/ExportBatchTask.cs @@ -291,8 +291,8 @@ public override void TaskComplete() : multilingualFileInfo.TargetLanguage.XPath; - var outputXmlNode = outputNode.SelectSingleNode(outputlanguagePath, nsmgr); - var multilingualXmlNode = multilingualNode.SelectSingleNode(outputlanguagePath, nsmgr); + var outputXmlNode = outputNode.SafeSelectSingleNode(outputlanguagePath, nsmgr); + var multilingualXmlNode = multilingualNode.SafeSelectSingleNode(outputlanguagePath, nsmgr); if (multilingualXmlNode == null) { diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Extensions/XMLDocumentExtensions.cs b/Multilingual XML FileType/Multilingual.XML.FileType/Extensions/XMLDocumentExtensions.cs index c2e73b8cf6..4588344dbe 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/Extensions/XMLDocumentExtensions.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Extensions/XMLDocumentExtensions.cs @@ -26,5 +26,16 @@ public static void AddAllNamespaces(this XmlDocument doc, XmlNamespaceManager ns } } } + + public static XmlNode SafeSelectSingleNode(this XmlNode node, string path, XmlNamespaceManager nsmgr) + { + if (string.IsNullOrWhiteSpace(path)) + return null; + + if (path.TrimStart().StartsWith("[")) + path = "(.)" + path; // parentheses make it valid for .NET XPath + + return node.SelectSingleNode(path, nsmgr); + } } } diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualParser.cs b/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualParser.cs index c751f65ee4..c734a0a066 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualParser.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualParser.cs @@ -196,7 +196,7 @@ public bool ParseNext() var xmlNode = nodes[index]; - var sourceXmlNode = xmlNode.SelectSingleNode(_sourceLanguage.XPath, _nsmgr); + var sourceXmlNode = xmlNode.SafeSelectSingleNode(_sourceLanguage.XPath, _nsmgr); var childNode = sourceXmlNode?.FirstChild; var isCdata = childNode?.NodeType == XmlNodeType.CDATA; @@ -238,7 +238,7 @@ private List GetParagraphLevelCommentNodes(XmlNode xmlNode) var allSegmentCommentXmlNodes = new List(); foreach (var languageMappingLanguage in LanguageMappingSettings.LanguageMappingLanguages) { - var languageXmlNode = xmlNode.SelectSingleNode(languageMappingLanguage.XPath, _nsmgr); + var languageXmlNode = xmlNode.SafeSelectSingleNode(languageMappingLanguage.XPath, _nsmgr); var languageComments = languageXmlNode?.SelectNodes(".//" + CommentMappingSettings.CommentElementName, _nsmgr); if (languageComments != null) { diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualWriter.cs b/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualWriter.cs index 4ed26ca833..9494183ca9 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualWriter.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Services/BilingualWriter.cs @@ -441,7 +441,7 @@ private XmlNode GetXmlNode(bool isSource) private XmlNode GetXmlUnitNode(XmlNode xmlUnit, string xPath) { - var xmlNode = xmlUnit.SelectSingleNode(xPath, _nsmgr); + var xmlNode = xmlUnit.SafeSelectSingleNode(xPath, _nsmgr); if (xmlNode == null) { xmlNode = _xmlNodeService.AddXmlNode(xmlUnit, xPath); diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Services/XMLFileSniffer.cs b/Multilingual XML FileType/Multilingual.XML.FileType/Services/XMLFileSniffer.cs index 3fc2300709..65e84aa7b4 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/Services/XMLFileSniffer.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Services/XMLFileSniffer.cs @@ -110,14 +110,19 @@ private bool IsFileSupported(string filePath, string namespaceUri, Encoding enco } var nodes = document.SelectNodes(_languageMappingSettings.LanguageMappingLanguagesXPath, nsmgr); - var node = nodes?.Item(0); - - supported = _languageMappingSettings.LanguageMappingLanguages.Select(language => - node?.SelectSingleNode(language.XPath, nsmgr)).Any(target => target != null); + foreach (XmlNode node in nodes) + { + if (_languageMappingSettings.LanguageMappingLanguages.Select(language => + node?.SafeSelectSingleNode(language.XPath, nsmgr)).Any(target => target != null) == true) + { + return true; + } + + } } } - return supported; + return false; } } } diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Services/XmlNodeService.cs b/Multilingual XML FileType/Multilingual.XML.FileType/Services/XmlNodeService.cs index 56c6b749a2..a31fbcc853 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/Services/XmlNodeService.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Services/XmlNodeService.cs @@ -1,4 +1,5 @@ -using System; +using Multilingual.XML.FileType.Extensions; +using System; using System.Collections.Generic; using System.Text.RegularExpressions; using System.Xml; @@ -50,12 +51,12 @@ public XmlNode AddXmlNode(XmlNode xmlUnit, string xPath) var queryNode = GetQueryNode(xmlNodeName, validAttributes); - var existingNode = xmlNode.SelectSingleNode(queryNode, _nsmgr); + var existingNode = xmlNode.SafeSelectSingleNode(queryNode, _nsmgr); if (existingNode == null && !string.IsNullOrEmpty(normalizedXmlNodeName)) { xmlNodeName = normalizedXmlNodeName; queryNode = GetQueryNode(normalizedXmlNodeName, validAttributes); - existingNode = xmlNode.SelectSingleNode(queryNode, _nsmgr); + existingNode = xmlNode.SafeSelectSingleNode(queryNode, _nsmgr); } if (existingNode == null) { From 49b534de979a5faa5b92f3802ec9a9cc98c1f923 Mon Sep 17 00:00:00 2001 From: flowAlexS Date: Tue, 9 Sep 2025 16:41:45 +0300 Subject: [PATCH 3/3] Multilingual XML FileType 3.1.2.1: - Enhanced the ImportBatchTask so that subsegments from Placeholder Tags are always assigned the correct ParagraphUnitId. --- .../BatchTasks/ImportBatchTask.cs | 24 ++++++++++++++++--- .../Properties/AssemblyInfo.cs | 2 +- .../pluginpackage.manifest.xml | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/BatchTasks/ImportBatchTask.cs b/Multilingual XML FileType/Multilingual.XML.FileType/BatchTasks/ImportBatchTask.cs index 2c198cd595..d62e2563fa 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/BatchTasks/ImportBatchTask.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/BatchTasks/ImportBatchTask.cs @@ -276,7 +276,7 @@ private List AlignParagraphUnits(IReadOnlyList AlignParagraphUnits(IReadOnlyList AlignParagraphUnits(IReadOnlyList AlignParagraphUnits(IReadOnlyList segmentPairs, bool isSource) + private void EnsureTagSubSegments(IPlaceholderTag placeholder, ParagraphUnitInfo paragraphUnitInfo) + { + foreach (var subSegment in placeholder.SubSegments) + { + subSegment.ParagraphUnitId = new ParagraphUnitId(paragraphUnitInfo.ParagraphUnitId); + } + } + + private void UpdateSegments(IAbstractMarkupDataContainer container, IEnumerable segmentPairs, bool isSource) { for (var index = 0; index < container.Count; index++) { diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/Properties/AssemblyInfo.cs b/Multilingual XML FileType/Multilingual.XML.FileType/Properties/AssemblyInfo.cs index b6186b595c..c73ebaacb0 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/Properties/AssemblyInfo.cs +++ b/Multilingual XML FileType/Multilingual.XML.FileType/Properties/AssemblyInfo.cs @@ -28,4 +28,4 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("3.0.0.0")] -[assembly: AssemblyFileVersion("3.1.2.0")] +[assembly: AssemblyFileVersion("3.1.2.1")] diff --git a/Multilingual XML FileType/Multilingual.XML.FileType/pluginpackage.manifest.xml b/Multilingual XML FileType/Multilingual.XML.FileType/pluginpackage.manifest.xml index 7827d9b321..2b9dbf5e67 100644 --- a/Multilingual XML FileType/Multilingual.XML.FileType/pluginpackage.manifest.xml +++ b/Multilingual XML FileType/Multilingual.XML.FileType/pluginpackage.manifest.xml @@ -1,7 +1,7 @@ Multilingual XML FileType - 3.1.2.0 + 3.1.2.1 Multilingual XML File Type Trados AppStore Team