如何在 C# 中更新 srgs 语法
how to update srgs grammar in C#
我已经创建了用于语义识别的 srgs 文件,现在我想更新 myGrammar 文件,现在我如何更新 my_Grammar.xml 文件并在文本框中的项目标签中添加更多城市。在这方面提供帮助 material 将不胜感激,并提前致谢。
<grammar version="1.0" xml:lang="en-US" mode="voice" root="destination"
xmlns="http://www.w3.org/2001/06/grammar" tag-format="semantics/1.0">
<rule id="Source">
<one-of>
<item> Karachi </item>
<item> Lahore </item>
<item> Abbottabad </item>
<item> Murree </item>
</one-of>
</rule>
<rule id="destination">
<one-of>
<item> Karachi </item>
<item> Lahore </item>
<item> Islamabad </item>
</one-of>
</rule>
<rule id="Article">
<one-of>
<item> to</item>
</one-of>
</rule>
</grammar>
SrgsRule SrcRule = new SrgsRule("id_Source");
SrgsOneOf SrcList = new SrgsOneOf(new string[] { "Lahore","Karachi",Abbottabad ,"Murree"});
SrcRule.Add(SrcList);
SrgsRule ArticleRule = new SrgsRule("id_Article");
SrgsOneOf ArticleList = new SrgsOneOf(new string[] { "to" });
ArticleRule.Add(ArticleList);
SrgsRule desRule = new SrgsRule("id_Destination");
SrgsOneOf desList = new SrgsOneOf(new string[] { "Islamabad","Lahore","Karachi",Abbottabad ,"Murree"});
desRule.Add(desList);
SrgsRule rootRule = new SrgsRule("Src_Article_des");
rootRule.Scope = SrgsRuleScope.Public;
SrgsRuleRef SrcRef = new SrgsRuleRef(SrcRule, "theSource");
rootRule.Add(SrcRef);
SrgsRuleRef ArticleRef = new SrgsRuleRef(ArticleRule, "theArticle");
rootRule.Add(ArticleRef);
SrgsRuleRef desRef = new SrgsRuleRef(desRule, "theDestination");
rootRule.Add(desRef);
SrgsDocument document = new SrgsDocument();
document.Rules.Add(new SrgsRule[] { rootRule, SrcRule, ArticleRule, desRule });
document.Root = rootRule;
Grammar g = new Grammar(document, "Src_Article_des");
sr.LoadGrammar(g);
System.Xml.XmlWriter writer =
System.Xml.XmlWriter.Create("c:\test\myGrammar.xml");
document.WriteSrgs(writer);
writer.Close();
试试这个。我使用了 XML Linq,但你也可以直接使用 XML.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication32
{
class Program
{
static void Main(string[] args)
{
string input =
"<one-of>" +
"<item>" +
//add item dynamically. // i want to add item here
"</item>" +
"<item> " +
//add new items.// i want to add item here
"</item>" +
"</one-of>";
XDocument doc = XDocument.Parse(input);
List<XElement> items = doc.Descendants().Where(x => x.Name == "item").ToList();
foreach (XElement item in items)
{
XElement newElement = new XElement("newItem", "i want to add item here");
item.Add(newElement);
}
}
}
}
public void AddItemToRule(string inFile, string outFile, string ruleId, string itemVal)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(inFile); // loads xml file
if (AddItemToRule(xmlDoc, ruleId, item))
{
xmlDoc.Save(outFile);
MessageBox.Show(@"Inserted Successfully");
}
}
public bool AddItemToRule(XmlDocument xmlDoc, string ruleId, string itemVal)
{
string ns = "http://www.w3.org/2001/06/grammar";
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsMgr.AddNamespace("g", ns);
System.Diagnostics.Debug.WriteLine(nsMgr.DefaultNamespace);
XmlNode foundNode = xmlDoc.SelectSingleNode("//g:rule[@id='" + ruleId + "']/g:one-of", nsMgr);
if (foundNode != null)
{
XmlElement eleItem = xmlDoc.CreateElement("item");
var text = xmlDoc.CreateTextNode(item);
eleItem.AppendChild(text);
foundNode.AppendChild(eleItem);
return true;
}
return false;
}
AddItemToRule(path, path, "id_Source", itemValue);
AddItemToRule(path, path, "id_Article", itemValue);
AddItemToRule(path, path, "id_Destination", itemValue);
此外,您可以创建简单的 grxml 文件(不使用编程方式),然后通过添加新元素来更新文件。
好吧,我知道这有点晚了,但由于我没有找到这个问题的任何正确答案,我想放弃我的解决方案,使用 SrgsDocument class:
public void UpdateVoiceCommand(string ruleId, SrgsRule updatedRule, string grammarFileName)
{
SrgsDocument grammarXmlDoc = new SrgsDocument(grammarFileName);
SrgsRulesCollection rules;
rules = grammarXmlDoc.Rules;
if (rules.Contains(ruleId))
rules.Remove(ruleId); //Remove old grammar rule
rules.Add(newRule); //Add replacement rule
saveSrgsDocument(GrammarFileName, grammarXmlDoc);
}
这会将新规则放在语法文件的末尾,但是通过使用 Insert 方法,您可以将它放在任何您想要的地方:
if (rules.Contains(ruleId)) //First check if the rule exists
{
SrgsRule oldRule = rules[ruleId]; //Get the old rule
int index = rules.IndexOf(oldRule); //Find it's position
rules.Remove(ruleId); //Remove it
rules.Insert(index, newRule); //Insert new rule at the position of the old rule
}
else
rules.Add(newRule); //Append a new rule at the end
我已经创建了用于语义识别的 srgs 文件,现在我想更新 myGrammar 文件,现在我如何更新 my_Grammar.xml 文件并在文本框中的项目标签中添加更多城市。在这方面提供帮助 material 将不胜感激,并提前致谢。
<grammar version="1.0" xml:lang="en-US" mode="voice" root="destination"
xmlns="http://www.w3.org/2001/06/grammar" tag-format="semantics/1.0">
<rule id="Source">
<one-of>
<item> Karachi </item>
<item> Lahore </item>
<item> Abbottabad </item>
<item> Murree </item>
</one-of>
</rule>
<rule id="destination">
<one-of>
<item> Karachi </item>
<item> Lahore </item>
<item> Islamabad </item>
</one-of>
</rule>
<rule id="Article">
<one-of>
<item> to</item>
</one-of>
</rule>
</grammar>
SrgsRule SrcRule = new SrgsRule("id_Source");
SrgsOneOf SrcList = new SrgsOneOf(new string[] { "Lahore","Karachi",Abbottabad ,"Murree"});
SrcRule.Add(SrcList);
SrgsRule ArticleRule = new SrgsRule("id_Article");
SrgsOneOf ArticleList = new SrgsOneOf(new string[] { "to" });
ArticleRule.Add(ArticleList);
SrgsRule desRule = new SrgsRule("id_Destination");
SrgsOneOf desList = new SrgsOneOf(new string[] { "Islamabad","Lahore","Karachi",Abbottabad ,"Murree"});
desRule.Add(desList);
SrgsRule rootRule = new SrgsRule("Src_Article_des");
rootRule.Scope = SrgsRuleScope.Public;
SrgsRuleRef SrcRef = new SrgsRuleRef(SrcRule, "theSource");
rootRule.Add(SrcRef);
SrgsRuleRef ArticleRef = new SrgsRuleRef(ArticleRule, "theArticle");
rootRule.Add(ArticleRef);
SrgsRuleRef desRef = new SrgsRuleRef(desRule, "theDestination");
rootRule.Add(desRef);
SrgsDocument document = new SrgsDocument();
document.Rules.Add(new SrgsRule[] { rootRule, SrcRule, ArticleRule, desRule });
document.Root = rootRule;
Grammar g = new Grammar(document, "Src_Article_des");
sr.LoadGrammar(g);
System.Xml.XmlWriter writer =
System.Xml.XmlWriter.Create("c:\test\myGrammar.xml");
document.WriteSrgs(writer);
writer.Close();
试试这个。我使用了 XML Linq,但你也可以直接使用 XML.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication32
{
class Program
{
static void Main(string[] args)
{
string input =
"<one-of>" +
"<item>" +
//add item dynamically. // i want to add item here
"</item>" +
"<item> " +
//add new items.// i want to add item here
"</item>" +
"</one-of>";
XDocument doc = XDocument.Parse(input);
List<XElement> items = doc.Descendants().Where(x => x.Name == "item").ToList();
foreach (XElement item in items)
{
XElement newElement = new XElement("newItem", "i want to add item here");
item.Add(newElement);
}
}
}
}
public void AddItemToRule(string inFile, string outFile, string ruleId, string itemVal)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(inFile); // loads xml file
if (AddItemToRule(xmlDoc, ruleId, item))
{
xmlDoc.Save(outFile);
MessageBox.Show(@"Inserted Successfully");
}
}
public bool AddItemToRule(XmlDocument xmlDoc, string ruleId, string itemVal)
{
string ns = "http://www.w3.org/2001/06/grammar";
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsMgr.AddNamespace("g", ns);
System.Diagnostics.Debug.WriteLine(nsMgr.DefaultNamespace);
XmlNode foundNode = xmlDoc.SelectSingleNode("//g:rule[@id='" + ruleId + "']/g:one-of", nsMgr);
if (foundNode != null)
{
XmlElement eleItem = xmlDoc.CreateElement("item");
var text = xmlDoc.CreateTextNode(item);
eleItem.AppendChild(text);
foundNode.AppendChild(eleItem);
return true;
}
return false;
}
AddItemToRule(path, path, "id_Source", itemValue);
AddItemToRule(path, path, "id_Article", itemValue);
AddItemToRule(path, path, "id_Destination", itemValue);
此外,您可以创建简单的 grxml 文件(不使用编程方式),然后通过添加新元素来更新文件。
好吧,我知道这有点晚了,但由于我没有找到这个问题的任何正确答案,我想放弃我的解决方案,使用 SrgsDocument class:
public void UpdateVoiceCommand(string ruleId, SrgsRule updatedRule, string grammarFileName)
{
SrgsDocument grammarXmlDoc = new SrgsDocument(grammarFileName);
SrgsRulesCollection rules;
rules = grammarXmlDoc.Rules;
if (rules.Contains(ruleId))
rules.Remove(ruleId); //Remove old grammar rule
rules.Add(newRule); //Add replacement rule
saveSrgsDocument(GrammarFileName, grammarXmlDoc);
}
这会将新规则放在语法文件的末尾,但是通过使用 Insert 方法,您可以将它放在任何您想要的地方:
if (rules.Contains(ruleId)) //First check if the rule exists
{
SrgsRule oldRule = rules[ruleId]; //Get the old rule
int index = rules.IndexOf(oldRule); //Find it's position
rules.Remove(ruleId); //Remove it
rules.Insert(index, newRule); //Insert new rule at the position of the old rule
}
else
rules.Add(newRule); //Append a new rule at the end