使用xsl将属性移动到子元素xml

使用xsl将属性移动到子元素xml,xml,xslt,Xml,Xslt,我一直在尝试将属性从一个元素移动到另一个元素,但它会创建另一个子元素 我有以下几点 <wrapper> <Person ID="1"> <Person InfoName="bob" Gender="male" /> <Purchase Reference = "1" Item="book"/> <Purchase Reference = "2" Item="shoes"/> </Person> <Pe

我一直在尝试将属性从一个元素移动到另一个元素,但它会创建另一个子元素

我有以下几点

<wrapper>
 <Person ID="1">
  <Person InfoName="bob" Gender="male" />
  <Purchase Reference = "1" Item="book"/>
  <Purchase Reference = "2" Item="shoes"/>
 </Person>
 <Person ID="2">
  <Person InfoName="Jane" Gender="female"/>
  <Purchase Reference = "1" Item="pen"/>
  <Purchase Reference = "2" Item="hat"/>
 </Person>
</wrapper>

我需要有以下内容(我不想保留,因为所有记录都会有ID):


我尝试了几种不同的XSLT,取得了不同程度的成功。下面将创建一个新的子节点

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:output method="xml" indent="yes"/>

   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()"/>
      </xsl:copy>
   </xsl:template>

   <xsl:template match="*[@ID]">
      <xsl:copy>
         <xsl:apply-templates select="@*[name() != 'ID']" />
         <xsl:element name="{name()}ID">
            <xsl:value-of select="@ID" />
         </xsl:element>
         <xsl:apply-templates select="node()"/>
      </xsl:copy>
   </xsl:template>

试着这样做:

XSLT1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Person/*">
    <xsl:copy>
        <xsl:apply-templates select="@*|../@ID|node()"/>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

应用于以下格式良好的输入:

<Wrapper>
<Person ID ="1">
 <Person Name="bob" Gender="male" />
 <Purchase Reference = "1" Item="book"/>
 <Purchase Reference = "2" Item="shoes"/>
</Person>

<Person ID ="2">
 <Person Name="Jane" Gender="female"/>
 <Purchase Reference = "1" Item="pen"/>
 <Purchase Reference = "2" Item="hat"/>
</Person>
</Wrapper>

结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<Wrapper>
   <Person ID="1">
      <Person ID="1" Name="bob" Gender="male"/>
      <Purchase ID="1" Reference="1" Item="book"/>
      <Purchase ID="1" Reference="2" Item="shoes"/>
   </Person>
   <Person ID="2">
      <Person ID="2" Name="Jane" Gender="female"/>
      <Purchase ID="2" Reference="1" Item="pen"/>
      <Purchase ID="2" Reference="2" Item="hat"/>
   </Person>
</Wrapper>

(1)注意有效的xml。属性必须是键值对,例如
info=“a”
(值必须位于
)中。XML区分大小写

(2) 您的解决方案要简单得多:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="wrapper/Person/*">
        <xsl:copy>
            <xsl:apply-templates select="@* | ../@ID"/>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>


通过
包装器/Person/*
选择要复制到的元素,并通过
将父级的属性
ID
grep。
这是迄今为止唯一的解决方案,它将
ID
属性放在最后——如所需:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Person/*">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="../@ID"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档时

<wrapper>
    <Person ID="1">
        <Person InfoName="bob" Gender="male" />
        <Purchase Reference = "1" Item="book"/>
        <Purchase Reference = "2" Item="shoes"/>
    </Person>
    <Person ID="2">
        <Person InfoName="Jane" Gender="female"/>
        <Purchase Reference = "1" Item="pen"/>
        <Purchase Reference = "2" Item="hat"/>
    </Person>
</wrapper>
<wrapper>
   <Person ID="1">
      <Person InfoName="bob" Gender="male" ID="1"/>
      <Purchase Reference="1" Item="book" ID="1"/>
      <Purchase Reference="2" Item="shoes" ID="1"/>
   </Person>
   <Person ID="2">
      <Person InfoName="Jane" Gender="female" ID="2"/>
      <Purchase Reference="1" Item="pen" ID="2"/>
      <Purchase Reference="2" Item="hat" ID="2"/>
   </Person>
</wrapper>

生成所需的精确结果(与其他解决方案的结果不同)

<wrapper>
    <Person ID="1">
        <Person InfoName="bob" Gender="male" />
        <Purchase Reference = "1" Item="book"/>
        <Purchase Reference = "2" Item="shoes"/>
    </Person>
    <Person ID="2">
        <Person InfoName="Jane" Gender="female"/>
        <Purchase Reference = "1" Item="pen"/>
        <Purchase Reference = "2" Item="hat"/>
    </Person>
</wrapper>
<wrapper>
   <Person ID="1">
      <Person InfoName="bob" Gender="male" ID="1"/>
      <Purchase Reference="1" Item="book" ID="1"/>
      <Purchase Reference="2" Item="shoes" ID="1"/>
   </Person>
   <Person ID="2">
      <Person InfoName="Jane" Gender="female" ID="2"/>
      <Purchase Reference="1" Item="pen" ID="2"/>
      <Purchase Reference="2" Item="hat" ID="2"/>
   </Person>
</wrapper>


您的输入不是格式良好的XML!非常感谢您的回答,我们对此表示赞赏…转换的目的是为了让我能够将XML文件导入access以供进一步检查,我已经使用XML Spy为我完成了这项工作,因此不再需要XSLT…I.Alam,请参阅添加了
ID
attrib的解决方案ute是最后一个——正如您在问题中所想的那样。其他两个解决方案将其作为第一个解决方案……XML规范明确指出,属性的顺序并不重要。XSLT处理器可以以任何顺序输出它们。试图通过XSLT样式表控制顺序是毫无意义的;使用一个处理器的方法可能不起作用另一个。非常感谢您的回答,非常感谢……转换的目的是让我可以将XML文件导入access以供进一步检查,我已经使用XML Spy为我完成了这项工作,因此不再需要XSLT