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

时间:2016-10-13 12:41:40

标签: xml xslt

我一直在尝试将属性从一个元素移动到另一个元素,而是创建另一个子元素。

我有以下

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

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

我尝试了几种不同的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>

3 个答案:

答案 0 :(得分:0)

以这种方式尝试:

XSLT 1.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 :(得分:0)

(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>

选择要复制到wrapper/Person/*的元素,然后通过ID grep父级的..属性。

答案 2 :(得分:0)

这是迄今为止唯一的解决方案,它将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>