C# 转换XML,使其所有元素和属性有效地成为;最小值1“;
我想转换一个复杂的XML元素,使其结构变得“规则”——该元素中任何位置的所有子元素和属性都将出现在其100%的节点中 这可能更容易表达我的意思 样本输入:C# 转换XML,使其所有元素和属性有效地成为;最小值1“;,c#,xml,.net-3.5,C#,Xml,.net 3.5,我想转换一个复杂的XML元素,使其结构变得“规则”——该元素中任何位置的所有子元素和属性都将出现在其100%的节点中 这可能更容易表达我的意思 样本输入: <product> <size name="S"/> <size> <stock>10</stock> </size> </product> <product> &l
<product>
<size name="S"/>
<size>
<stock>10</stock>
</size>
</product>
<product>
<size name="S">
<stock/>
</size>
<size name="">
<stock>10</stock>
</size>
</product>
10
所需输出:
<product>
<size name="S"/>
<size>
<stock>10</stock>
</size>
</product>
<product>
<size name="S">
<stock/>
</size>
<size name="">
<stock>10</stock>
</size>
</product>
10
发生了什么:
<product>
<size name="S"/>
<size>
<stock>10</stock>
</size>
</product>
<product>
<size name="S">
<stock/>
</size>
<size name="">
<stock>10</stock>
</size>
</product>
第一个size
元素提供了一个空的子元素stock
(因为第二个size
元素有一个)
属性<代码>/size@name带有空值的被添加到第二个size
子元素(因为第一个size
元素有一个)
先决条件:
<product>
<size name="S"/>
<size>
<stock>10</stock>
</size>
</product>
<product>
<size name="S">
<stock/>
</size>
<size name="">
<stock>10</stock>
</size>
</product>
- 处理后的XML不太可能很大(使用LINQ、将所有XML缓存在内存中等都没有问题)
- 我事先不知道它的XML模式
- 以下代码应符合您的期望
使用此test.xml文件作为输入
<product xmlns="http://www.example.com/schemas/v0.1">
<size name="S"/>
<size>
<stock>
<a.el a.att="a.value"/>
</stock>
</size>
<size>
<stock>
10
<b.el b.att="b.value"/>
</stock>
</size>
<size size.att="size.value" name="e">
<stock>
12
<b.el b.att2="b.value2"/>
</stock>
</size>
</product>
10
12
这将生成以下有效且规范化的输出
<product xmlns="http://www.example.com/schemas/v0.1">
<size name="S" size.att="">
<stock>
<a.el a.att=""></a.el>
<b.el b.att="" b.att2=""></b.el>
</stock>
</size>
<size name="" size.att="">
<stock>
<a.el a.att="a.value" />
<b.el b.att="" b.att2=""></b.el>
</stock>
</size>
<size name="" size.att="">
<stock>
10
<b.el b.att="b.value" b.att2="" /><a.el a.att=""></a.el></stock>
</size>
<size size.att="size.value" name="e">
<stock>
12
<b.el b.att2="b.value2" b.att="" /><a.el a.att=""></a.el></stock>
</size>
</product>
10
12
使用系统;
使用System.Collections.Generic;
使用System.Xml;
使用System.Xml.Linq;
使用System.Xml.XPath;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
XDocument xDoc=XDocument.Load(“test.xml”);
XNamespace ns=xDoc.Root.Name.Namespace;
var mgr=new-XmlNamespaceManager(new-NameTable());
mgr.AddNamespace(“ns”,ns.ToString());
var elements=xDoc.XPathSelectElements(“/ns:product/ns:size”,mgr);
Descriptor desc=Descriptor.InferFrom(元素);
描述规范化(元素);
Write(xDoc.ToString());
}
}
公共类描述符
{
私有只读IList_attributeNames=新列表();
私有只读IDictionary _elementDescriptors=新字典();
公共XName名称{get;private set;}
公共IEnumerable AttributeNames{get{return\u AttributeNames;}}
公共IEnumerable元素描述符{get{return}ElementDescriptors;}}
私有void UpdateNameFrom(XElement元素)
{
if(Name==null)
{
Name=element.Name;
返回;
}
if(element.Name==Name)
返回;
抛出新的InvalidOperationException();
}
私人无效添加(XAttribute att)
{
XName名称=附件名称;
if(_attributeNames.Contains(name))
返回;
_attributeNames.Add(名称);
}
公共静态描述符推断自(IEnumerable元素)
{
var desc=新描述符();
foreach(元素中的var元素)
推断内部(元素,描述);
返回描述;
}
私有静态void InferFromInternal(XElement元素,描述符描述)
{
desc.UpdateNameFrom(元素);
foreach(element.Attributes()中的var att)
说明添加(附件);
foreach(element.Elements()中的var子元素)
描述添加(子元素);
}
专用空心添加(XElement子元素)
{
描述符描述;
if(_elementDescriptors.ContainsKey(subElement.Name))
desc=_element描述符[subElement.Name];
其他的
{
desc=新描述符();
_elementDescriptors.Add(subElement.Name,desc);
}
推断内部(子元素,描述);
}
公共无效规范化(IEnumerable元素)
{
foreach(元素中的var元素)
标准化内部(元素);
}
私有void NormalizeInternal(XElement元素)
{
if(element.Name!=名称)
抛出新的InvalidOperationException();
foreach(attributeName中的var属性)
{
var att=元素属性(属性);
如果(att!=null)
继续;
添加(新的XAttribute(属性,string.Empty));
}
foreach(元素描述符中的var属性)
{
XElement el=element.element(attribute.Key);
如果(el==null)
{
el=新的XElement(attribute.Key,string.Empty);
元素。添加(el);
}
属性.Value.NormalizeInternal(el);
}
}
}
}
格式错误的XML来自哪里?你能改变它的建造方式吗?只是想更好地了解您的场景。我实际上没有尝试编写任何解决方案,我的想法是在文档上递归迭代并创建某种字典,在那里我们将存储(对于遇到的每个元素)其所有子元素和属性,即使它们只出现一次。之后,我将再次迭代该文档。这是可行的,只是感觉“又快又脏”。我想知道是否有一些更聪明的技巧(我知道XSLT转换,但从未使用过它,甚至不知道它们是否适用于这里)。@DJ Quimby-它本身并没有畸形。它是一个包含商业报价的XML;产品及其数据。应用程序用户定义what is what(哪个元素或属性