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