Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 转换XML,使其所有元素和属性有效地成为;最小值1“;_C#_Xml_.net 3.5 - Fatal编程技术网

C# 转换XML,使其所有元素和属性有效地成为;最小值1“;

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

我想转换一个复杂的XML元素,使其结构变得“规则”——该元素中任何位置的所有子元素和属性都将出现在其100%的节点中

这可能更容易表达我的意思

样本输入:

<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(哪个元素或属性