无限制的XML元素到名称/值对,而不重复XSLT中的元素名称

时间:2015-02-08 19:31:24

标签: xml xslt xslt-1.0 xslt-2.0

我编写了一个xslt来将输入xml文件转换为名称/值对。

输入xml如下:

Input.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<EMailData>  
<PersonInfo>
  <PersonID>PersonID1092</PersonID>
  <EmailAddress>EmailAddress1093</EmailAddress>
  <SecureToken>SecureToken1094</SecureToken>
  <ContactPrimaryChannel>ContactPrimaryChannel1172</ContactPrimaryChannel>
     <Order>
     <OrderID>OrderID1224</OrderID>
     <CustomerOrderNumber>CustomerOrderNumber1225</CustomerOrderNumber>
     <OrderType/>
     <Currency>Currency1226</Currency>
     <OrderName/>
     <OrderFrequency>OrderFrequency1227</OrderFrequency>
     <IsRepeatDeliveryOrder>IsRepeatDeliveryOrder1228</IsRepeatDeliveryOrder>
     <ProjectedShipmentDate>2015-02-05</ProjectedShipmentDate>
     <NextShipmentDate>2015-02-05</NextShipmentDate>
     <Total>1229</Total>
  </Order>
  <Order>
     <OrderID>OrderID1259</OrderID>
     <CustomerOrderNumber>CustomerOrderNumber1260</CustomerOrderNumber>
     <OrderType/>
     <Currency>Currency1261</Currency>
     <OrderName/>
     <OrderFrequency>OrderFrequency1262</OrderFrequency>
     <IsRepeatDeliveryOrder>IsRepeatDeliveryOrder1263</IsRepeatDeliveryOrder>
     <ProjectedShipmentDate>2015-02-05</ProjectedShipmentDate>
     <NextShipmentDate>2015-02-05</NextShipmentDate>
     <Total>1264</Total>
  </Order>
  </PersonInfo>
 </EMailData>

我希望以这种方式获得所需的输出:

Desired_OUTPUT.XML

<?xml version="1.0" encoding="UTF-8"?>
<EMailData>

<property name="EVENTINFO">
  <property name="PersonInfo">
     ------
     values
     ------
     <property name="Order">
        <row>
           ----
           values
           ----           
        </row>
        <row> <!-- Only Row Value Repeated For More than One Order -->
           ----
           values
           ----
        </row>
     </property>
     </property>
</property>

这是我使用的XSLT。

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="xml" indent="yes"/>

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

<xsl:template match="EMailData/PersonInfo">
<property name="EVENTINFO">
  <property name="{local-name()}">
     <xsl:apply-templates select="@*|node()"/>
  </property>
</property>
</xsl:template>

<xsl:template match="EMailData/PersonInfo/*">
  <property name="{local-name()}">
    <value>
     <xsl:apply-templates />
    </value>
  </property>
</xsl:template>


<!-- Order begins -->

<xsl:template match="EMailData/PersonInfo/Order">   
  <property name="{local-name()}">
<row> 
     <xsl:apply-templates select="@*|node()"/>
</row>   
  </property>
</xsl:template>

<xsl:template match="EMailData/PersonInfo/Order/*">
  <property name="{local-name()}">
    <value>
     <xsl:apply-templates />
    </value>
  </property>
</xsl:template>

<!-- Order Ends -->

</xsl:stylesheet>

应用此xslt之后,我将输出显示为:

<?xml version="1.0" encoding="UTF-8"?>
<EMailData>

<property name="EVENTINFO">
  <property name="PersonInfo">
     ------
     values
     ------
     <property name="Order">
        <row>
           ----
           values
           ----           
        </row>
    </property> 
    <property name="Order"> <!-- The Order Name is repeated -->
        <row>
           ----
           values
           ----
        </row>
     </property>
  </property>
</property>
</EMailData>

请告诉我应该在哪里更改我的XSLT。提前谢谢!

1 个答案:

答案 0 :(得分:1)

太糟糕了,你只向我们展示了部分输出;这使得很难理解这里究竟是什么问题。在我看来,它应该足够只做:

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="PersonInfo">
    <property name="EVENTINFO">
        <property name="PersonInfo">
            <xsl:apply-templates select="@*|node()[not(self::Order)]"/>
            <property name="Order">
                <xsl:apply-templates select="Order"/>
            </property>
        </property>
    </property>
</xsl:template>

<xsl:template match="Order">
        <row>
            <xsl:apply-templates />
        </row>
</xsl:template>

</xsl:stylesheet>

应用于您的示例输入,结果为:

<?xml version="1.0" encoding="UTF-8"?>
<EMailData>
   <property name="EVENTINFO">
      <property name="PersonInfo">
         <PersonID>PersonID1092</PersonID>
         <EmailAddress>EmailAddress1093</EmailAddress>
         <SecureToken>SecureToken1094</SecureToken>
         <ContactPrimaryChannel>ContactPrimaryChannel1172</ContactPrimaryChannel>
         <property name="Order">
            <row>
               <OrderID>OrderID1224</OrderID>
               <CustomerOrderNumber>CustomerOrderNumber1225</CustomerOrderNumber>
               <OrderType/>
               <Currency>Currency1226</Currency>
               <OrderName/>
               <OrderFrequency>OrderFrequency1227</OrderFrequency>
               <IsRepeatDeliveryOrder>IsRepeatDeliveryOrder1228</IsRepeatDeliveryOrder>
               <ProjectedShipmentDate>2015-02-05</ProjectedShipmentDate>
               <NextShipmentDate>2015-02-05</NextShipmentDate>
               <Total>1229</Total>
            </row>
            <row>
               <OrderID>OrderID1259</OrderID>
               <CustomerOrderNumber>CustomerOrderNumber1260</CustomerOrderNumber>
               <OrderType/>
               <Currency>Currency1261</Currency>
               <OrderName/>
               <OrderFrequency>OrderFrequency1262</OrderFrequency>
               <IsRepeatDeliveryOrder>IsRepeatDeliveryOrder1263</IsRepeatDeliveryOrder>
               <ProjectedShipmentDate>2015-02-05</ProjectedShipmentDate>
               <NextShipmentDate>2015-02-05</NextShipmentDate>
               <Total>1264</Total>
            </row>
         </property>
      </property>
   </property>
</EMailData>