XSLT 到 xml 中的最后一级子节点

XSLT to last level child nodes in xml

我正在尝试将嵌套的输入 xml 展平,子节点的名称为 parentnode.childnode

<?xml version="1.0" encoding="UTF-8"?>
<queryResponse>
  <Account>
    <Id>1</Id>
    <Name>AA</Name>
    <RecordTypeId>1</RecordTypeId>
    <RecordType>
      <Id>1</Id>
      <DeveloperName>A</DeveloperName>
    </RecordType>
  </Account>
  <Account>
    <Id>2</Id>
    <Name>BB</Name>
    <RecordTypeId>2</RecordTypeId>
    <RecordType>
      <Id>2</Id>
      <DeveloperName>B</DeveloperName>
    </RecordType>
  </Account>
  </queryResponse>

预期输出

<?xml version="1.0" encoding="UTF-8"?>
<queryResponse>
  <Account>
    <Id>1</Id>
    <Name>AA</Name>
    <RecordTypeId>1</RecordTypeId>
    <RecordType.Id>1</RecordType.Id><RecordType.DeveloperName>A</RecordType.DeveloperName>
  </Account>
  <Account>
    <Id>2</Id>
    <Name>BB</Name>
    <RecordTypeId>2</RecordTypeId>
    <RecordType.Id>2</RecordType.Id><RecordType.DeveloperName>B</RecordType.DeveloperName>
  </Account>
  </queryResponse>

当前 XSLT 代码,(动态地)查找具有子节点的节点并更改子节点名称。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 
       
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>  
        </xsl:copy> 
        
           
    </xsl:template>
   
      <xsl:template match="*/*/*"> 
         <xsl:for-each select="*">
             <xsl:element name="{concat(name(..),'.',name())}"> 
          <xsl:apply-templates select="node()"/> 
         </xsl:element>
         </xsl:for-each>   
         
     </xsl:template> 
       
</xsl:stylesheet>

并获得以下输出,其中大子节点名称已更改但其他节点未被复制,你能帮我看看我遗漏了什么吗

<?xml version="1.0" encoding="UTF-8"?><queryResponse>
  <Account>
    <RecordType.Id>1</RecordType.Id><RecordType.DeveloperName>A</RecordType.DeveloperName>
  </Account>
  <Account>
    <RecordType.Id>2</RecordType.Id><RecordType.DeveloperName>B</RecordType.DeveloperName>
  </Account>
  </queryResponse>

将 for-each select 更改为 select 当前匹配的元素(如果它没有任何子元素)或其后代元素:

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

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

    <xsl:template match="/*/*/*">
        <xsl:for-each select=".[not(*)]|.//*">
            <xsl:element name="{concat(name(..),'.',name())}"> 
                <xsl:apply-templates select="@*|node()"/> 
            </xsl:element>  
        </xsl:for-each>
    </xsl:template> 

</xsl:stylesheet>

您可以删除 for-each 并使用两个专门的模板:

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

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>  
        </xsl:copy> 
    </xsl:template>
    <!--If we are at least 3 levels deep and do not have any child elements,
        rename it -->
    <xsl:template match="/*/*//*[not(*)]">
        <xsl:element name="{concat(name(..),'.',name())}"> 
            <xsl:apply-templates select="@*|node()"/> 
        </xsl:element>  
    </xsl:template> 

    <!--If we are at least 3 levels deep and have any child elements,
        keep going-->
    <xsl:template match="/*/*//*[*]">
        <xsl:apply-templates select="*"/>
    </xsl:template>

</xsl:stylesheet>