我需要构建以下XML文档
<?xml version="1.0"?>
<SFDocument>
<TableID>5415</TableID>
<PageSize>1</PageSize>
<PageIndex>1</PageIndex>
<MultiCompany>No</MultiCompany>
<Language>1033</Language>
<Fields>
<Field>Operation No.</Field>
<Field>Line No.</Field>
<Field>Date</Field>
<Field>Comment</Field>
</Fields>
<TableFilters>
<TableFilter>
<Field>Status</Field>
<Filter>3</Filter>
</TableFilter>
<TableFilter>
<Field>Prod. Order No.</Field>
<Filter>101006</Filter>
</TableFilter>
</TableFilters>
<Key>
<Field>Routing Reference No</Field>
<Field>10000</Field>
</Key>
</SFDocument>使用下面的代码,它可以工作,但它是否是正确的方法。
internal class Field
{
public string Name { get; set; }
public const string FieldName = "Field";
}
internal class Key
{
public string Field { get; set; }
public const string FieldName = "Field";
}
internal class TableFilter
{
public string Field { get; set; }
public string Filter { get; set; }
public const string FieldName = "Field";
public const string FilterName = "FilterName";
}
void Main()
{
//this part is just for the example, obviously, this would be passed as parameter
var tableId = 5415;
var pageSize = 1;
var pageIndex = 1;
var multiCompany = "No";
var language = 1033;
var fields = new List<Field>();
fields.Add(new Field() {Name = "Operation No."});
fields.Add(new Field() {Name = "Line No."});
fields.Add(new Field() {Name = "Date"});
fields.Add(new Field() {Name = "Comment"});
var tableFilters = new List<TableFilter>();
tableFilters.Add(new TableFilter() {Field = "Status", Filter = "3"});
tableFilters.Add(new TableFilter() {Field = "Prod. Order No.", Filter = "101006"});
var keys = new List<Key>();
keys.Add(new Key() {Field = "Routing Reference No"});
keys.Add(new Key() {Field = "10000"});
//End of setup
XDocument doc = new XDocument(new XElement("SFDocument",
new XElement("TableId", tableId),
new XElement("PageSize", pageSize),
new XElement("PageIndex", pageIndex),
new XElement("MultiCompany", multiCompany),
new XElement("Language", language),
new XElement("Fields"),
new XElement("TableFilters"),
new XElement("Key")
)
);
var xFields = doc.Element("SFDocument").Element("Fields");
foreach (Field field in fields)
{
xFields.Add(new XElement(Field.FieldName, field.Name));
}
var xTableFilters = doc.Element("SFDocument").Element("TableFilters");
foreach (TableFilter tableFilter in tableFilters)
{
var tf = new XElement("TableFilter");
tf.Add(new XElement(TableFilter.FieldName, tableFilter.Field));
tf.Add(new XElement(TableFilter.FilterName, tableFilter.Filter ));
xTableFilters.Add(tf);
}
var xKey = doc.Element("SFDocument").Element("Key");
foreach (Key key in keys)
{
xKey.Add(new XElement(Key.FieldName, key.Field));
}
doc.Dump(); //Using LinqPad
}发布于 2013-11-28 20:14:41
最后,我更改了我的方法,并使用了一个序列化方法:
public static class SerializationHelper
{
internal static string SerializeObject<T>(this T toSerialize)
{
var xmlSerializer = new XmlSerializer(toSerialize.GetType());
var textWriter = new StringWriter();
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
[Serializable]
public class SFDocument
{
public int TableId { get; set; }
public int PageSize { get; set; }
public int PageIndex { get; set; }
public string MultiCompany { get; set; }
public int Language { get; set; }
[XmlArrayItem("Field")]
public List<string> Fields { get; set; }
public List<TableFilter> TableFilters { get; set; }
[XmlArrayItem("Field")]
public List<string> Key { get; set; }
public SFDocument(): this(5415, 1, 1, "No", 1033){}
public SFDocument(int tableId, int pageSize, int pageIndex, string multiCompany, int language)
{
TableId = tableId;
PageSize = pageSize;
PageIndex = pageIndex;
MultiCompany = multiCompany;
Language = language;
Fields = new List<string>();
Key = new List<string>();
TableFilters = new List<TableFilter>();
}
}
[Serializable]
public class TableFilter
{
public string Field { get; set; }
public string Filter { get; set; }
public TableFilter() {}
public TableFilter(string field, string filter)
{
Field = field;
Filter = filter;
}
}
void Main()
{
var sfd = new SFDocument();
sfd.Fields.Add("Field1");
sfd.Fields.Add("Field2");
sfd.Fields.Add("Field3");
sfd.Fields.Add("Field4");
sfd.Key.Add("Key1");
sfd.Key.Add("Key2");
sfd.Key.Add("Key3");
sfd.TableFilters.Add(new TableFilter("field1", "filter1"));
sfd.TableFilters.Add(new TableFilter("field2", "filter2"));
sfd.TableFilters.Add(new TableFilter("field3", "filter3"));
sfd.SerializeObject().Dump();
}发布于 2013-11-29 01:05:27
使用XML序列化肯定是一种有效的方法。但是,如果您想继续使用LINQ,我将修改代码,使其更具声明性。这样,代码的结构将与XML的结构非常相似,因此更清楚地看到发生了什么:
XDocument doc = new XDocument(
new XElement(
"SFDocument",
new XElement("TableId", tableId),
new XElement("PageSize", pageSize),
new XElement("PageIndex", pageIndex),
new XElement("MultiCompany", multiCompany),
new XElement("Language", language),
new XElement(
"Fields", fields.Select(field => new XElement(Field.FieldName, field.Name))),
new XElement(
"TableFilters",
tableFilters.Select(
tableFilter =>
new XElement(
"TableFilter",
new XElement(TableFilter.FieldName, tableFilter.Field),
new XElement(TableFilter.FilterName, tableFilter.Filter)))),
new XElement("Key", keys.Select(key => new XElement(Key.FieldName, key.Field)))));尽管TableFilters元素对于这种方法来说可能太复杂了。但您可以轻松地将其重构为另一种方法:
private static XElement CreateTableFilters(IEnumerable<TableFilter> tableFilters)
{
return new XElement(
"TableFilters",
tableFilters.Select(
tableFilter =>
new XElement(
"TableFilter",
new XElement(TableFilter.FieldName, tableFilter.Field),
new XElement(TableFilter.FilterName, tableFilter.Filter))));
}
…
XDocument doc = new XDocument(
new XElement(
"SFDocument",
new XElement("TableId", tableId),
new XElement("PageSize", pageSize),
new XElement("PageIndex", pageIndex),
new XElement("MultiCompany", multiCompany),
new XElement("Language", language),
new XElement(
"Fields", fields.Select(field => new XElement(Field.FieldName, field.Name))),
CreateTableFilters(tableFilters),
new XElement("Key", keys.Select(key => new XElement(Key.FieldName, key.Field)))));发布于 2013-11-27 22:58:30
回到使用.NET 2.0时,我编写了从XmlElement继承的Tag类和从XmlDocument继承的XmlBuilder。由于遗留的原因,我们仍然使用它,但我确信它可以作为几个扩展方法被重写成代码的一半。
下面是一个小样本:
XmlBuilder xml = new XmlBuilder("AmazonEnvelope");
xml.AddNamespace("noNamespaceSchemaLocation", "amzn-envelope.xsd");
XmlBuilder.Tag message = xml.FirstTag.AddTag("Message");
message.AddTag("MessageID", messageID++);
message.AddTag("OperationType", "PartialUpdate");
XmlBuilder.Tag product = message.AddTag("Product");
product.AddTag("SKU", part.ID);
if (part.upcCode.Length == 12)
{
XmlBuilder.Tag UPC = product.AddTag("StandardProductID");
UPC.AddTag("Type", "UPC");
UPC.AddTag("Value", part.upcCode);
}
else if (part.upcCode.Length == 13)
{
XmlBuilder.Tag UPC = product.AddTag("StandardProductID");
UPC.AddTag("Type", "EAN");
UPC.AddTag("Value", part.upcCode);
}
product.AddTag("ProductTaxCode", "A_GEN_TAX");
return xml.OuterXmlXmlBuilder构造函数只接受字符串并使用该字符串创建第一个节点:
_outerNode = new Tag(qualifiedName, this);
AppendChild(_outerNode);xml.FirstTag只是一个将_outerNode作为Tag (而不是XmlElement)的调用。
等等..。
这让您可以轻松地添加许多逻辑(“我要添加这组标记吗?”),它不需要大量的news,以后您可以返回并向标记添加更多内容。
https://codereview.stackexchange.com/questions/36238
复制相似问题