我目前正在使用Microsoft Kinect SDK开发语音识别应用程序,输出应该是遵循特定结构的XML文件,例如:
<?xml version="1.0" encoding="UTF-8"?>
<Speech>
<Item Words="hello" Confidence="0,5705749" Semantic="Child" />
<Item Words="goodbye" Confidence="0,7705913" Semantic="Child" />
</Speech>
项目节点包含识别Kinect语音识别器的所有读取信息。目标是:每次识别新单词时,都会添加一个新的<Item>
节点及其相应的属性。
我遇到了更新过程的问题,即每次添加新节点时,它都会覆盖最后一个仅以<Item>
节点结束的节点。我已经搜索过并尝试从搜索结果中应用解决方案,但没有成功。
写入XML文件的函数如下:
void WriteXML(string result, float confidence, string semantic, string typeOfSpeech)
{
try
{
//pick whatever filename with .xml extension
string filename = "XML" + "SpeechOutput" + ".xml";
XmlDocument xmlDoc = new XmlDocument();
try
{
xmlDoc.Load(filename);
}
catch (System.IO.FileNotFoundException)
{
//if file is not found, create a new xml file
XmlTextWriter xmlWriter = new XmlTextWriter(filename, System.Text.Encoding.UTF8);
xmlWriter.Formatting = Formatting.Indented;
xmlWriter.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
xmlWriter.WriteStartElement("Speech");
xmlWriter.Close();
xmlDoc.Load(filename);
}
XmlNode root = xmlDoc.DocumentElement;
XmlNode lastWord = root.LastChild;
XmlElement childNode = xmlDoc.CreateElement("Item");
childNode.SetAttribute("Words", result);
childNode.SetAttribute("Confidence", confidence.ToString());
childNode.SetAttribute("Semantic", semantic);
root.InsertAfter(childNode, lastWord);
xmlDoc.Save("W:\\" + filename);
}
catch (Exception ex)
{
WriteError(ex.ToString());
}
}
非常感谢任何帮助!
为了便于测试,我将代码添加到更简单的应用程序中以测试此方法:
namespace XMLTesting
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private string typeOfSpeech;
public MainWindow()
{
InitializeComponent();
WriteXML("test", 1, "semantic", "typeofspeech");
WriteXML("test2", 2, "semantic", "typeofspeech");
}
void WriteXML(string result, float confidence, string semantic, string typeOfSpeech)
{
try
{
//pick whatever filename with .xml extension
string filename = "XML" + "SpeechOutput" + ".xml";
XmlDocument xmlDoc = new XmlDocument();
try
{
xmlDoc.Load(filename);
}
catch (System.IO.FileNotFoundException)
{
//if file is not found, create a new xml file
XmlTextWriter xmlWriter = new XmlTextWriter(filename, System.Text.Encoding.UTF8);
xmlWriter.Formatting = Formatting.Indented;
xmlWriter.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
xmlWriter.WriteStartElement("Speech");
xmlWriter.Close();
xmlDoc.Load(filename);
}
XmlNode root = xmlDoc.DocumentElement;
XmlNode lastWord = root.LastChild;
XmlElement childNode = xmlDoc.CreateElement("Item");
childNode.SetAttribute("Words", result);
childNode.SetAttribute("Confidence", confidence.ToString());
childNode.SetAttribute("Semantic", semantic);
root.InsertAfter(childNode, lastWord);
xmlDoc.Save("W:\\" + filename);
}
catch (Exception ex)
{
WriteError(ex.ToString());
}
}
void WriteError(string str)
{
//outputBox.Text = str;
}
}
}
此应用程序的输出文件是:
<?xml version="1.0" encoding="UTF-8"?>
<Speech>
<Item Words="test2" Confidence="2" Semantic="semantic" />
</Speech>
而不是:
<?xml version="1.0" encoding="UTF-8"?>
<Speech>
<Item Words="test" Confidence="1" Semantic="semantic" />
<Item Words="test2" Confidence="2" Semantic="semantic" />
</Speech>
答案 0 :(得分:0)
如果使用XmlDocument类是必要的,那么我可以建议一些增强功能:
略微修改后的WriteXml
(适用于我):
void WriteXML(string result, float confidence, string semantic, string typeOfSpeech)
{
try
{
//pick whatever filename with .xml extension
string filename = Path.Combine("W:\\", "XMLSpeechOutput.xml");
//if file is not found, create a new xml file
if (!File.Exists(filename))
{
XmlTextWriter xmlWriter = new XmlTextWriter(filename, System.Text.Encoding.UTF8);
xmlWriter.Formatting = Formatting.Indented;
xmlWriter.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
xmlWriter.WriteStartElement("Speech");
xmlWriter.Close();
}
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filename);
XmlNode root = xmlDoc.DocumentElement;
XmlNode lastWord = root.LastChild;
XmlElement childNode = xmlDoc.CreateElement("Item");
childNode.SetAttribute("Words", result);
childNode.SetAttribute("Confidence", confidence.ToString());
childNode.SetAttribute("Semantic", semantic);
root.InsertAfter(childNode, lastWord);
xmlDoc.Save(filename);
}
catch (Exception ex)
{
WriteError(ex.ToString());
}
}
如果您可以使用其他技术来访问/修改XML结构,那么我建议您使用LINQ2XML - 对于当前问题,使用将减少代码行。我的示例包含两个扩展方法:
扩展代码:
public static class ProjectExtensions
{
/// <summary>
/// Loads the file with the specified name.
/// If the file does not exist an empty file is created.
/// </summary>
/// <param name="xmlFile">File location with name: c:\xml\input.xml</param>
/// <returns>A filled XDocument object</returns>
public static XDocument CreateOrLoad(this String xmlFile)
{
// if the XML file does not exist
if (!File.Exists(xmlFile))
{
// create an empty file
var emptyXml = new XElement("Speech");
// and save it under the specified name (and location)
emptyXml.Save(xmlFile);
}
// load the file (it was either created or it exists already)
return XDocument.Load(xmlFile);
}
/// <summary>
/// Adds new row at the end of the specified XML document.
/// </summary>
/// <param name="result">TODO</param>
/// <param name="confidence">TODO</param>
/// <param name="semantic">TODO</param>
public static void AppendRow(this XDocument document, string result, float confidence, string semantic, string typeOfSpeech)
{
// prepare/construct the row to add
var row = new XElement("Item", new XAttribute("Word", result),
new XAttribute("Precision", confidence.ToString()),
new XAttribute("Semantic", semantic));
// take the root node
var root = document.Root;
// the xml is empty
if (!root.Elements().Any())
{
// just add the node
root.Add(row);
}
else
{
// add the node after at the end of the file
root.Elements().Last().AddAfterSelf(row);
}
}
}
可以像这样使用:
var filename = "W:\\XMLSpeechOut.xml";
//
var xml = filename.CreateOrLoad();
xml.AppendRow("A", 10.5f, "B", "C");
xml.AppendRow("D", 11.0f, "E", "F");
xml.Save(filename);
// alternative one-liner usage (open or create, append, save)
filename.CreateOrLoad().AppendRow("G", 11.5f, "H", "I").Save(filename);
输出结果为:
<?xml version="1.0" encoding="utf-8"?>
<Speech>
<Item Word="A" Precision="10,5" Semantic="B" />
<Item Word="D" Precision="11" Semantic="E" />
<Item Word="G" Precision="11,5" Semantic="H" />
</Speech>