【问题标题】:How to copy a structure of nodes from one xml to an other with a different namespace?如何将节点结构从一个xml复制到另一个具有不同命名空间的xml?
【发布时间】:2008-10-30 11:38:11
【问题描述】:

我有两个具有两个不同 XSD 架构和不同名称空间的 XML 文件。它们都具有相同的子结构。现在我需要将该节点(和所有子节点)从一个 XML 文档复制到另一个。

如果命名空间相同,克隆就可以了。有什么好的方法吗? (子结构稍后会改变 - 但会保持不变。)

【问题讨论】:

    标签: c# xml


    【解决方案1】:

    基本上,您需要一个 XSL 转换来创建名称相同但名称空间不同的新元素。

    考虑以下输入 XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <test xmlns="http://tempuri.org/ns_old">
        <child attrib="value">text</child>
    </test>
    

    现在您需要一个模板,上面写着“复制您看到的所有内容的结构和名称,但在您使用它时声明一个新的命名空间”:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:old="http://tempuri.org/ns_old"
    >
      <xsl:output method="xml" version="1.0" 
        encoding="UTF-8" indent="yes" omit-xml-declaration="no" 
      />
    
      <xsl:template match="node()|@*">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="old:*">
        <xsl:element name="{local-name()}" namespace="http://tempuri.org/ns_new">
          <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
      </xsl:template>
    
    </xsl:stylesheet>
    

    当您通过它运行上述 XML 时,会产生:

    <?xml version="1.0" encoding="UTF-8"?>
    <test xmlns="http://tempuri.org/ns_new">
      <child attrib="value">text</child>
    </test>
    

    您所有的http://tempuri.org/ns_old 元素都有效地更改了它们的命名空间。当您的输入 XML 同时具有多个命名空间时,XSL 很可能必须进行一些扩展。

    【讨论】:

      【解决方案2】:

      不确定这是否适用,但我在 vb.net 中使用两个 xml 文档做了类似的事情:

      Private Shared Sub CopyElement(ByVal FromE As Xml.XmlElement, ByVal ToE As Xml.XmlElement)
          CopyElement(FromE, ToE, Nothing)
      End Sub
      Private Shared Sub CopyElement(ByVal FromE As Xml.XmlElement, ByVal ToE As Xml.XmlElement, ByVal overAttr As Xml.XmlAttributeCollection)
          Dim NewE As Xml.XmlElement
          Dim e As Xml.XmlElement
          NewE = ToE.OwnerDocument.CreateElement(FromE.Name)
      
          CopyAttributes(FromE, NewE)
          If Not overAttr Is Nothing Then
              OverrideAttributes(overAttr, NewE)
          End If
          For Each e In FromE
              CopyElement(e, NewE, overAttr)
          Next
          ToE.AppendChild(NewE)
      
      
      End Sub
      Private Shared Sub CopyAttributes(ByVal FromE As Xml.XmlElement, ByVal ToE As Xml.XmlElement)
          Dim a As Xml.XmlAttribute
          For Each a In FromE.Attributes
              ToE.SetAttribute(a.Name, a.Value)
          Next
      End Sub
      Private Shared Sub OverrideAttributes(ByVal AC As Xml.XmlAttributeCollection, ByVal E As Xml.XmlElement)
          Dim a As Xml.XmlAttribute
          For Each a In AC
              If Not E.Attributes.ItemOf(a.Name) Is Nothing Then
                  E.SetAttribute(a.Name, a.Value)
              End If
          Next
      End Sub
      

      【讨论】:

        【解决方案3】:

        遵循 Tomalak 的示例(稍作修正),但使用 SetAttribute + OuterXml + InnerXml 更简单 常量字符串 xml_str = @"

        文本测试> ";

        ";

        public static void RunSnippet()
        

        {

            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml_str);
        
            XmlElement elem = doc.DocumentElement["test"];
            WL( string.Format("[{0}]", elem ) );
            elem.SetAttribute("xmlns", "http://another.namespace.org/");
            WL( elem.OuterXml );
        
            XmlDocument another_doc = new XmlDocument();
            another_doc.LoadXml("<root/>");
            another_doc.DocumentElement.InnerXml = elem.OuterXml;
            WL( another_doc.DocumentElement.OuterXml );
        

        }

        【讨论】:

          【解决方案4】:

          如果您希望在匹配某个属性时复制节点的所有子元素。您只需复制引用节点的InnerXML 并将其设置为等于新节点即可。

          类似这样,下面,我有一个带有 Document ElementRoot 元素的 XML 块作为 Tablist,我需要在 Tablist 下添加新节点Role="Ka"Ka的所有子节点都应该和XXX一样:

          <Tablist>
              <Designation Role="XXX">
                  <!--<Tab name="x" default="x"/>-->
                  <!--<Tab name="y" default="y"/>-->
                  <Tab name="r" default="r" />
                  <Tab name="rd" default="rd" />
                  <Tab name="qq" default="qq" />
                  <Tab name="ddd" default="ddd" />
                </Designation>
              <Designation Role="YYY">
                  <!--<Tab name="a" default="a"/>-->
                  <!--<Tab name="b" default="b"/>-->
                  <Tab name="c" default="c" />
                  <Tab name="dd" default="dd" />
                  <Tab name="ee" default="ee" />
                  <Tab name="f" default="f" />
                </Designation>
              </Tablist>
          

          所以我只写以下代码:

          XmlDocument objXmlDocument1 = null;
          objXmlDocument1 = new XmlDocument();
          objXmlDocument1.Load(
              System.Web.HttpContext.Current.Server.MapPath("") + 
              "\\XMLSchema\\" + 
              "ABC.xml");
          
          XMLNodesList nodes1 = objXmlDocument1.GetElementsByTagName("Designation");
          foreach (XmlNode n in nodes1) {
              if (n.Attributes["Role"].Value.Trim().Equals("XXX"){                                
                  objnode1 = n;
                  break;
              }
          }
          if (objnode1 != null){
              XmlNodeList innerNodes1 = objnode1.ChildNodes;
              XmlNode newNode1 = objXmlDocument1.CreateElement("Designation");
              XmlAttribute newAtt1 = objXmlDocument1.CreateAttribute("Role");
              newAtt1.Value = "Ka";
              newNode1.Attributes.Append(newAtt1);
              newNode1.InnerXml=objnode1.InnerXml;
              objXmlDocument1.DocumentElement.AppendChild(newNode1);
          }
          objXmlDocument1.Save(
              System.Web.HttpContext.Current.Server.MapPath("") + 
              "\\XMLSchema\\" + 
              "ABC.xml");
          

          【讨论】:

            猜你喜欢
            • 2012-07-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-11-04
            • 1970-01-01
            相关资源
            最近更新 更多