Предотвращение дублирования отправки формы показывает способ сделать это без JavaScript.
Я думаю, что для правильной работы ReadXml в этом случае вам необходимо указать схему в вашем XML-файле. В противном случае читатель не будет знать, что делать с типами данных.
Как только вы определите свое пространство имен XML, используемое в элементах XML, вы можете легко импортировать его - без проблем.
Вам нужно, чтобы ваш XML выглядел примерно так:
<Catalog xmlns:dt="some-xml-namespace-here">
<Rec>
<ITEM dt:dt="string"/>
<QTY dt:dt="string">1</QTY>
<SUB dt:dt="string">1</SUB>
<CATALOG dt:dt="string">ABC123</CATALOG>
</Rec>
.....
</Catalog>
После того, как я это сделаю, ваши две строки кода работают как шарм, и данные будут импортированы без проблем (в 5 таблиц внутри DataSet).
Marc
Это сделает его доступным для синтаксического анализа. Пространство имен dt обычно относится к xmlns: dt = "urn: schemas-microsoft-com: datatypes". Что-то или кто-то испортил ваш XML, но если вы должны иметь возможность импортировать его, вы можете просто изменить атрибуты xmlns в элементе каталога, как показано:
string xml = @"<Catalog xmlns=""dt"" xmlns:dt=""dt"">
<Rec>
<ITEM dt:dt=""string""/>
<QTY dt:dt=""string"">1</QTY>
<SUB dt:dt=""string"">1</SUB>
<CATALOG dt:dt=""string"">ABC123</CATALOG>
</Rec>
<Rec>
<ITEM dt:dt=""string""/>
<QTY dt:dt=""string"">1</QTY>
<SUB dt:dt=""string"">1</SUB>
<CATALOG dt:dt=""string"">ABC124</CATALOG>
</Rec>
<Rec>
<ITEM dt:dt=""string""/>
<QTY dt:dt=""string"">1</QTY>
<SUB dt:dt=""string"">1</SUB>
<CATALOG dt:dt=""string"">ABC125</CATALOG>
</Rec>
</Catalog>";
DataSet ds = new DataSet("Whatev");
TextReader txtReader = new StringReader(xml);
XmlReader reader = new XmlTextReader(txtReader);
ds.ReadXml(reader);
Debug.Assert(ds.Tables.Count ==5);
Debug.Assert((string)ds.Tables[2].Rows[0][0] == "string");
Debug.Assert((string)ds.Tables[3].Rows[0][1] == "1");
Также Марк прав, но с определением выше вы можете сгенерировать соответствие схема:
<xs:schema xmlns:dt="dt" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="dt" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:element name="Catalog"><xs:complexType> <xs:sequence><xs:element maxOccurs="unbounded" name="Rec"><xs:complexType><xs:sequence><xs:element name="ITEM"><xs:complexType><xs:attribute ref="dt:dt" use="required" /></xs:complexType></xs:element><xs:element name="QTY"><xs:complexType>
<xs:simpleContent><xs:extension base="xs:unsignedByte"><xs:attribute ref="dt:dt" use="required" /></xs:extension></xs:simpleContent></xs:complexType>
</xs:element><xs:element name="SUB"><xs:complexType><xs:simpleContent><xs:extension base="xs:unsignedByte"><xs:attribute ref="dt:dt" use="required" /></xs:extension></xs:simpleContent></xs:complexType></xs:element><xs:element name="CATALOG"><xs:complexType><xs:simpleContent><xs:extension base="xs:string"><xs:attribute ref="dt:dt" use="required" /></xs:extension></xs:simpleContent></xs:complexType></xs:element></xs:sequence></xs:complexType></xs:element></xs:sequence></xs:complexType></xs:element><xs:attribute name="dt" type="xs:string" /></xs:schema>
Атрибут «dt» является ссылочным атрибутом. Таким образом, xml не может быть действительным для любой схемы без объявления xmlns = "ds".
DataSet ds = new DataSet("Whatev");
DataTable catalog = ds.Tables.Add("Catalog");
DataColumn recCol = catalog.Columns.Add("Rec");
DataTable rec = ds.Tables.Add("Rec");
rec.Columns.AddRange(new DataColumn[] {
new DataColumn("ITEM", typeof(string)),
new DataColumn("QTY", typeof(string)),
new DataColumn("SUB", typeof(string)),
new DataColumn("CATALOG", typeof(string))
});
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
foreach (XmlNode recNode in doc.GetElementsByTagName("Rec"))
{
DataRow row = rec.Rows.Add(
recNode["ITEM"].InnerText,
recNode["QTY"].InnerText,
recNode["SUB"].InnerText,
recNode["CATALOG"].InnerText);
}
Вот и все. Теперь будет две таблицы: Каталог и Рек. Я подозреваю, что вам нужен только Rec, потому что Каталог бесполезен. Поэтому просто удалите код данных каталога, если это так, или добавьте атрибут id в каждую строку каталога и свяжите его с rec:
DataSet ds = new DataSet("Whatev");
DataTable catalog = ds.Tables.Add("Catalog");
DataColumn idCol = catalog.Columns.Add("Id");
DataTable rec = ds.Tables.Add("Rec");
rec.Columns.AddRange(new DataColumn[] {
new DataColumn("ITEM", typeof(string)),
new DataColumn("QTY", typeof(string)),
new DataColumn("SUB", typeof(string)),
new DataColumn("CATALOG", typeof(string))
});
catalog.ChildRelations.Add("catToRecRelation", idCol, rec.Columns["CATALOG"]);
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
foreach (XmlNode recNode in doc.GetElementsByTagName("Rec"))
{
// Create id in parent Catalog node, based on CATALOG value
catalog.Rows.Add(recNode["CATALOG"].InnerText);
DataRow row = rec.Rows.Add(
recNode["ITEM"].InnerText,
recNode["QTY"].InnerText,
recNode["SUB"].InnerText,
recNode["CATALOG"].InnerText);
}
var childRows = catalog.Rows[0].GetChildRows("catToRecRelation");