Почему '[' рассматривается как часть имени XmlElement?
Я пытаюсь написать метод, который будет запрашивать любую таблицу SQLite и возвращать ее содержимое в виде XML:
// Get any table's contents as XML; caveat: table can have at most 25 columns (this can be increased if necessary)
string IHHSDBUtils.GenericSaveDataAndReturnAsXML(string DBTableName)
{
String xmlOutput = String.Empty;
String qry = String.Format("SELECT * FROM {0}", DBTableName);
try // catch
{
using (SQLiteConnection conn = new SQLiteConnection(HHSUtils.GetDBConnection()))
{
conn.Open();
XmlDocument doc = new XmlDocument();
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
doc.AppendChild(dec); // Create the root element
XmlElement root = doc.CreateElement("Command");
doc.AppendChild(root);
try
{
using (SQLiteCommand cmd = new SQLiteCommand(qry, conn))
{
using (SQLiteDataReader rdr = cmd.ExecuteReader())
{
int colCount = rdr.FieldCount;
while (rdr.Read())
{
// outer val
XmlElement tblRec = doc.CreateElement(DBTableName);
if (colCount > 0)
{
String firstCol = rdr[0].ToString();
XmlElement _firstCol = doc.CreateElement(rdr[0].ToString()); //
Will this return the right val?
_firstCol.InnerText = firstCol;
tblRec.AppendChild(_firstCol);
}
if (colCount > 1)
{
String secondCol = rdr[1].ToString();
XmlElement _secondCol = doc.CreateElement(rdr[1].ToString());
_secondCol.InnerText = secondCol;
tblRec.AppendChild(_secondCol);
}
. . .
if (colCount > 25)
{
String twentysixthCol = rdr[25].ToString();
XmlElement _twentysixthCol =
doc.CreateElement(rdr[25].ToString());
_twentysixthCol.InnerText = twentysixthCol;
tblRec.AppendChild(_twentysixthCol);
}
root.AppendChild(tblRec);
} // while
} // using (SQLiteDataReader
} // using (SQLiteCommand
}
finally
{
xmlOutput = doc.OuterXml;
doc.Save(String.Format("{0}.xml", DBTableName));
}
} // using (SQLiteConnection
} // try..catch
catch (Exception ex)
{
String msgInnerExAndStackTrace = String.Format(
"{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException,
ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(String.Format("From
HHSDBUtils.GenericSaveDataAndReturnAsXML: {0}", msgInnerExAndStackTrace));
}
return xmlOutput;
}
Я передал этому методу имя таблицы, которая содержит менее 25 столбцов (если быть точным, 16), назвав ее (тестирование) следующим образом:
MessageBox.Show(hhsdbutils.GenericSaveDataAndReturnAsXML("Inventory"));
Но вместо того, чтобы вернуть возвышенно правильно сформированный блок xml, я получил это решительное коммюнике:
The '[' character, hexadecimal value 0x5B, cannot be included in a name.; Inner Ex: ; Stack
Trace: at System.Xml.XmlDocument.CheckName(String name)
at System.Xml.XmlElement..ctor(XmlName name, Boolean empty, XmlDocument doc)
at System.Xml.XmlDocument.CreateElement(String prefix, String localName, String namespaceURI)
at System.Xml.XmlDocument.CreateElement(String name)
at HHS.SQLiteHHSDBUtils.HHS.IHHSDBUtils.GenericSaveDataAndReturnAsXML(String DBTableName)
У меня есть некоторые значения-заполнители, заключенные в квадратные скобки, как видно из LINQPad:
Это (с такими значениями, как "[CRVid]" в таблице) проблема? Если да, то какие еще "нечетные" символы мне следует избегать, чтобы в столбце содержались значения: "{", "}", "(", ")" и т. Д.?
ОБНОВИТЬ
Я изобразил код, подталкивая большого пальца (получил спину)
string IHHSDBUtils.GenericSaveDataAndReturnAsXML(string DBTableName)
{
String xmlOutput = String.Empty;
String qry = String.Format("SELECT * FROM {0}", DBTableName);
try // catch
{
using (SQLiteConnection conn = new SQLiteConnection(HHSUtils.GetDBConnection()))
{
conn.Open();
XmlDocument doc = new XmlDocument();
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
doc.AppendChild(dec); // Create the root element
XmlElement root = doc.CreateElement("Command");
doc.AppendChild(root);
// Note that to set the text inside the element,
// you use .InnerText instead of .Value (which will throw an exception).
// You use SetAttribute to set attribute
try
{
using (SQLiteCommand cmd = new SQLiteCommand(qry, conn))
{
using (SQLiteDataReader rdr = cmd.ExecuteReader())
{
// outer val
XmlElement tblRec = doc.CreateElement(DBTableName);
String colName;
XmlElement _colName;
int colCount = rdr.FieldCount;
for (int i = 0; i < colCount; i++)
{
rdr.Read();
colName = rdr[i].ToString();
_colName = doc.CreateElement(colName); // Will this return the right
val?
_colName.InnerText = colName;
tblRec.AppendChild(_colName);
}
root.AppendChild(tblRec);
} // using (SQLiteDataReader
} // using (SQLiteCommand
}
finally
{
xmlOutput = doc.OuterXml;
doc.Save(String.Format("{0}.xml", DBTableName));
}
} // using (SQLiteConnection
} // try..catch
catch (Exception ex)
{
String msgInnerExAndStackTrace = String.Format(
"{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException,
ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(String.Format("From
HHSDBUtils.GenericSaveDataAndReturnAsXML: {0}", msgInnerExAndStackTrace));
}
return xmlOutput;
}
... но теперь, хотя по какой-то причине исключение исчезло, возвращаемое значение val не содержит записи в таблице. Все, что я вижу, это:
<?xml version="1.0"?>
<Command>
<Inventory/>
</Command>
?
ОБНОВЛЕНИЕ 2
Curioser и curiouser: проблема с моим обновлением заключается в том, что у меня был тип глупого гуся (">", где это должно было быть "<"). Но даже с этим исправлено, я получаю исключение:
Date: 2/21/2009 12:54:12 AM
Message: From HHSDBUtils.GenericSaveDataAndReturnAsXML: No current row; Inner Ex: ; Stack
Trace: at System.Data.SQLite.SQLiteDataReader.CheckValidRow()
at System.Data.SQLite.SQLiteDataReader.GetValue(Int32 i)
at System.Data.SQLite.SQLiteDataReader.get_Item(Int32 i)
at HHS.SQLiteHHSDBUtils.HHS.IHHSDBUtils.GenericSaveDataAndReturnAsXML(String DBTableName)
... и возвращается только XML:
<?xml version="1.0"?>
<Command/>
???
ОБНОВЛЕНИЕ 3
Я изменил код на это:
string IHHSDBUtils.GenericSaveDataAsXML(string DBTableName)
{
String xmlOutput = String.Empty;
String qry = String.Format("SELECT * FROM {0}", DBTableName);
try // catch
{
using (SQLiteConnection conn = new SQLiteConnection(HHSUtils.GetDBConnection()))
{
conn.Open();
XmlDocument doc = new XmlDocument();
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
doc.AppendChild(dec); // Create the root element
XmlElement root = doc.CreateElement("Command");
doc.AppendChild(root);
// Note that to set the text inside the element,
// you use .InnerText instead of .Value (which will throw an exception).
// You use SetAttribute to set attribute
try
{
using (SQLiteCommand cmd = new SQLiteCommand(qry, conn))
{
using (SQLiteDataReader rdr = cmd.ExecuteReader())
{
//if (!rdr.HasRows) return; <= won't know this yet
// outer val
XmlElement tblRec = doc.CreateElement(DBTableName);
String colName;
XmlElement _colName;
while (rdr.Read())
{
int colCount = rdr.FieldCount;
for (int i = 0; i < colCount; i++)
{
colName = rdr[i].ToString();
_colName = doc.CreateElement(colName); // Will this return the right val?
_colName.InnerText = colName;
tblRec.AppendChild(_colName);
rdr.Read();
}
root.AppendChild(tblRec);
} // while (rdr.Read())
} // using (SQLiteDataReader
} // using (SQLiteCommand
}
finally
{
xmlOutput = doc.OuterXml;
doc.Save(String.Format("{0}.xml", DBTableName));
}
} // using (SQLiteConnection
} // try..catch
catch (Exception ex)
{
String msgInnerExAndStackTrace = String.Format(
"{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(String.Format("From HHSDBUtils.GenericSaveDataAndReturnAsXML: {0}", msgInnerExAndStackTrace));
}
return xmlOutput;
}
... но все равно получите тот же результат ошибки msg и xml, как описано в обновлении 2.
1 ответ
Как насчет этого:
static string GenerateXmlFromTable(string tableName, bool useAttribute)
{
XmlDocument document = new XmlDocument();
XmlDeclaration declaration = document.CreateXmlDeclaration("1.0", null, null);
document.AppendChild(declaration);
XmlElement rootElement = document.CreateElement("Command");
document.AppendChild(rootElement);
using (SQLiteConnection connection = new SQLiteConnection("Data source=SqlLite.db"))
{
connection.Open();
string query = string.Format("Select * from {0}", tableName);
using(SQLiteCommand command = new SQLiteCommand(query, connection))
{
using(SQLiteDataReader reader = command.ExecuteReader())
{
while(reader.Read())
{
XmlElement recordElement = document.CreateElement(tableName);
rootElement.AppendChild(recordElement);
for(int index = 0; index < reader.FieldCount; index++)
{
if (useAttribute)
{
recordElement.SetAttribute(reader.GetName(index), reader.GetValue(index).ToString());
}
else
{
XmlElement valueElement = document.CreateElement(reader.GetName(index));
valueElement.InnerText = reader.GetValue(index).ToString();
recordElement.AppendChild(valueElement);
}
}
}
}
}
}
using(StringWriter stringWriter = new StringWriter(new StringBuilder()))
using(XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter))
{
xmlWriter.Formatting = Formatting.Indented;
document.Save(xmlWriter);
return stringWriter.ToString();
}
}