用于将属性转换为子元素并将当前元素的值放入其另一个新子元素的 XSLT 代码

XSLT code for converting attributes to child elements and putting the value of current element into its another new child element

我不知道 XSLT,请帮助: 我有以下 XML:

<OLifE>
  <Holding id="1234">
    <HoldingKey>1397650618090</HoldingKey>
    <HoldingTypeCode tc="2">Policy</HoldingTypeCode>
    <HoldingStatus tc="2">Inactive</HoldingStatus>
    <CarrierAdminSystem>PAS</CarrierAdminSystem>
  </Holding>
</OLifE>

我想要这样的输出:

<OLifE>
  <Holding>
    <id>1234</id>
    <HoldingKey>1397650618090</HoldingKey>
    <HoldingTypeCode>
      <tc>2</tc>
      <value>Policy</value>
    </HoldingTypeCode>
    <HoldingStatus>
      <tc>2</tc>
      <value>Inactive</value>
    </HoldingStatus>
    <CarrierAdminSystem>PAS</CarrierAdminSystem>
   </Holding>
 </OLifE>

请注意,所有属性都需要转换为子元素,但是对于指定了 tc 属性的元素:

<HoldingTypeCode tc="2">Policy</HoldingTypeCode>

需要小心处理。

我不想要这样的输出:

<HoldingTypeCode>
                <tc>2</tc>Policy</HoldingTypeCode>

我有以下需要稍微修改的 XSLT 代码:

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

 <xsl:output method="xml"/>

 <xsl:template match="*">
       <xsl:element name="{name()}">
            <xsl:for-each select="@*">
                 <xsl:element name="{name()}">
                       <xsl:value-of select="."/>
                 </xsl:element>
            </xsl:for-each>
            <xsl:apply-templates select="*|text()"/>
       </xsl:element>
 </xsl:template>

请帮忙。

我想你可以定义一个像这样的模板来调用你想要输出属性的地方:

<xsl:template name="transform.attrs">
  <xsl:for-each select="@*">
    <xsl:element name="{name()}">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:for-each>
</xsl:template>

对于大多数情况,您使用与以前几乎相同的模板,只需为属性调用新模板:

<xsl:template match="*">
   <xsl:element name="{name()}">
      <xsl:call-template name="transform.attrs">
      <xsl:apply-templates select="*|text()"/>
   </xsl:element>
</xsl:template>

对于特定元素,承载 @tc 属性:

<xsl:template match="*[@tc]">
  <xsl:element name="{name()}">
    <xsl:call-template name="transform.attrs" />
    <value>
       <xsl:apply-templates select="*|text()"/>
    </value>
  </xsl:element>
</xsl:template>

假设您想要一个通用解决方案,如何:

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="*"/>

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

<!-- attributes to elements -->
<xsl:template match="@*">
    <xsl:element name="{name()}">
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>

<!-- avoid mixed content -->
<xsl:template match="text()[../@*]">
    <value>
        <xsl:value-of select="."/>
    </value>
</xsl:template>

</xsl:stylesheet>

编辑

However, the root element in my original XML has got xmlns="some web address" attribute.

在这种情况下,将第一个模板更改为:

<!-- modified identity transform -->
<xsl:template match="*">
     <xsl:element name="{name()}">
        <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
</xsl:template>

这是假设您希望所有输出节点都不在命名空间中。