繁体   English   中英

如何将节点结构从一个xml复制到另一个具有不同名称空间的结构?

[英]How to copy a structure of nodes from one xml to an other with a different namespace?

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

如果名称空间相同,则将执行克隆操作。 有一个不错的方法吗? (子结构稍后会更改-但将保持不变。)

基本上,您需要一个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。

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

像这样的事情,下面,我有一个文档元素元素作为一个XML块Tablist ,我需要在添加新节点TablistRole="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");

不知道这是否适用,但是我对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

遵循Tomalak的示例(有一点点修复),但是使用SetAttribute + OuterXml + InnerXml更加简单,const字符串xml_str = @“

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

“;

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 );

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM