XSLT - 将子节点分组在同一父节点下
XSLT - Group child nodes under same parent
我有以下输入XML
输入XML
<bills>
<bill>
<billNo>1</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>1</serialNo>
</invoice>
</bill>
<bill>
<billNo>1</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>2</serialNo>
</invoice>
</bill>
<bill>
<billNo>2</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>1</serialNo>
</invoice>
</bill>
<bill>
<billNo>2</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>2</serialNo>
</invoice>
</bill>
<bill>
<billNo>2</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>3</serialNo>
</invoice>
</bill>
</bills>
需要转换为输出XML
输出XML
<bills>
<bill>
<billNo>1</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>1</serialNo>
</invoice>
<invoice>
<serialNo>2</serialNo>
</invoice>
</bill>
<bill>
<billNo>2</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>1</serialNo>
</invoice>
<invoice>
<serialNo>2</serialNo>
</invoice>
<invoice>
<serialNo>3</serialNo>
</invoice>
</bill>
</bills>
以下 XSLT 用于转换,但是我遗漏了一些东西,因为 bill
下的子节点也被重复复制,而不是仅 invoice
子节点及其子节点被复制。 XSL如下
XSL
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="key" match="bill" use="billNo" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="bill[generate-id() = generate-id(key('key', billNo)[1])]">
<bill>
<xsl:apply-templates select="key('key', billNo)/*" />
</bill>
</xsl:template>
<xsl:template match="bill" />
</xsl:stylesheet>
获得预期结果的一种方法是更改此设置:
<xsl:apply-templates select="key('key', billNo)/*" />
至:
<xsl:apply-templates select="billNo | exportType" />
<xsl:apply-templates select="key('key', billNo)/invoice" />
请注意,这假设 exportType
对于在公共 billNo
下分组的所有项目都是相同的。
我有以下输入XML
输入XML
<bills>
<bill>
<billNo>1</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>1</serialNo>
</invoice>
</bill>
<bill>
<billNo>1</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>2</serialNo>
</invoice>
</bill>
<bill>
<billNo>2</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>1</serialNo>
</invoice>
</bill>
<bill>
<billNo>2</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>2</serialNo>
</invoice>
</bill>
<bill>
<billNo>2</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>3</serialNo>
</invoice>
</bill>
</bills>
需要转换为输出XML
输出XML
<bills>
<bill>
<billNo>1</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>1</serialNo>
</invoice>
<invoice>
<serialNo>2</serialNo>
</invoice>
</bill>
<bill>
<billNo>2</billNo>
<exportType>1</exportType>
<invoice>
<serialNo>1</serialNo>
</invoice>
<invoice>
<serialNo>2</serialNo>
</invoice>
<invoice>
<serialNo>3</serialNo>
</invoice>
</bill>
</bills>
以下 XSLT 用于转换,但是我遗漏了一些东西,因为 bill
下的子节点也被重复复制,而不是仅 invoice
子节点及其子节点被复制。 XSL如下
XSL
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="key" match="bill" use="billNo" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="bill[generate-id() = generate-id(key('key', billNo)[1])]">
<bill>
<xsl:apply-templates select="key('key', billNo)/*" />
</bill>
</xsl:template>
<xsl:template match="bill" />
</xsl:stylesheet>
获得预期结果的一种方法是更改此设置:
<xsl:apply-templates select="key('key', billNo)/*" />
至:
<xsl:apply-templates select="billNo | exportType" />
<xsl:apply-templates select="key('key', billNo)/invoice" />
请注意,这假设 exportType
对于在公共 billNo
下分组的所有项目都是相同的。