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

时间:2018-03-16 14:32:53

标签: xml xslt parent-child flatten

我正在尝试压缩输入嵌套的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>

预期ouptut

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

1 个答案:

答案 0 :(得分:1)

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

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