使用 XSLT 对 XML 中的 Table 元素进行分组
Grouping Table elements in XML using XSLT
我已经在下面的转换代码中工作了很长时间。我不确定该要求在 XSLT 中是否可行,需要您的帮助来确定是否可以使用 XSLT。
我的输入XML如下,
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<base:callFlowResponse xmlns:base="http://schema/webservices.elink.solcorp.com">
<Messages>
<More/>
</Messages>
<OUTPUT>
<MIR-DV-INT>100</MIR-DV-INT>
<MIR-DEP-AMT>0000000000042832.50</MIR-DEP-AMT>
<MIR-DV-TOTAL-AMT-DUE>1000</MIR-DV-TOTAL-AMT-DUE>
<MIR-MAX-REM-TOP-PREM>1000</MIR-MAX-REM-TOP-PREM>
<MIR-DV-DUE-DT-G>
<TableMIR-DV-DUE-DT-T>
<MIR-DV-DUE-DT-T>2011-01-01</MIR-DV-DUE-DT-T>
<MIR-DV-DUE-DT-T/>
<MIR-DV-DUE-DT-T/>
</TableMIR-DV-DUE-DT-T>
</MIR-DV-DUE-DT-G>
<MIR-DV-POL-MPREM-AMT-G>
<TableMIR-DV-POL-MPREM-AMT-T>
<MIR-DV-POL-MPREM-AMT-T>1000</MIR-DV-POL-MPREM-AMT-T>
<MIR-DV-POL-MPREM-AMT-T/>
<MIR-DV-POL-MPREM-AMT-T/>
</TableMIR-DV-POL-MPREM-AMT-T>
</MIR-DV-POL-MPREM-AMT-G>
<MIR-DV-BASIC-SERV-TAX-AMT-G>
<TableMIR-DV-BASIC-SERV-TAX-AMT-T>
<MIR-DV-BASIC-SERV-TAX-AMT-T>10000</MIR-DV-BASIC-SERV-TAX-AMT-T>
<MIR-DV-BASIC-SERV-TAX-AMT-T/>
<MIR-DV-BASIC-SERV-TAX-AMT-T/>
</TableMIR-DV-BASIC-SERV-TAX-AMT-T>
</MIR-DV-BASIC-SERV-TAX-AMT-G>
<MIR-DV-TOTL-SW-CESS-AMT-G>
<TableMIR-DV-TOTL-SW-CESS-AMT-T>
<MIR-DV-TOTL-SW-CESS-AMT-T>1000</MIR-DV-TOTL-SW-CESS-AMT-T>
<MIR-DV-TOTL-SW-CESS-AMT-T/>
<MIR-DV-TOTL-SW-CESS-AMT-T/>
</TableMIR-DV-TOTL-SW-CESS-AMT-T>
</MIR-DV-TOTL-SW-CESS-AMT-G>
<MIR-DV-KR-KL-CESS-AMT-G>
<TableMIR-DV-KR-KL-CESS-AMT-T>
<MIR-DV-KR-KL-CESS-AMT-T>1000</MIR-DV-KR-KL-CESS-AMT-T>
<MIR-DV-KR-KL-CESS-AMT-T/>
<MIR-DV-KR-KL-CESS-AMT-T/>
</TableMIR-DV-KR-KL-CESS-AMT-T>
</MIR-DV-KR-KL-CESS-AMT-G>
<MIR-DV-PREM-AMT-G>
<TableMIR-DV-PREM-AMT-T>
<MIR-DV-PREM-AMT-T>10000</MIR-DV-PREM-AMT-T>
<MIR-DV-PREM-AMT-T/>
<MIR-DV-PREM-AMT-T/>
</TableMIR-DV-PREM-AMT-T>
</MIR-DV-PREM-AMT-G>
<MIR-DV-ADV-PREM-AMT>1000</MIR-DV-ADV-PREM-AMT>
<MIR-TOTL-SW-BH-CESS-TAX-AMT>1000</MIR-TOTL-SW-BH-CESS-TAX-AMT>
<MIR-KR-KL-CESS-TAX-AMT>1000</MIR-KR-KL-CESS-TAX-AMT>
</OUTPUT>
</base:callFlowResponse>
</S:Body>
</S:Envelope>
输出 XML 应该是,
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<base:callFlowResponse xmlns:base="http://schema/webservices.elink.solcorp.com">
<Messages>
<More/>
</Messages>
<OUTPUT>
<MIR-DV-INT>100</MIR-DV-INT>
<MIR-DEP-AMT>0000000000042832.50</MIR-DEP-AMT>
<MIR-DV-TOTAL-AMT-DUE>1000</MIR-DV-TOTAL-AMT-DUE>
<MIR-MAX-REM-TOP-PREM>1000</MIR-MAX-REM-TOP-PREM>
<GROUP-1>
<MIR-DV-DUE-DT-T>2011-01-01</MIR-DV-DUE-DT-T>
<MIR-DV-POL-MPREM-AMT-T>1000</MIR-DV-POL-MPREM-AMT-T>
<MIR-DV-BASIC-SERV-TAX-AMT-T>10000</MIR-DV-BASIC-SERV-TAX-AMT-T>
<MIR-DV-TOTL-SW-CESS-AMT-T>1000</MIR-DV-TOTL-SW-CESS-AMT-T>
<MIR-DV-KR-KL-CESS-AMT-T>1000</MIR-DV-KR-KL-CESS-AMT-T>
<MIR-DV-PREM-AMT-T>10000</MIR-DV-PREM-AMT-T>
</GROUP-1>
<GROUP-2>
<MIR-DV-DUE-DT-T></MIR-DV-DUE-DT-T>
<MIR-DV-POL-MPREM-AMT-T></MIR-DV-POL-MPREM-AMT-T>
<MIR-DV-BASIC-SERV-TAX-AMT-T></MIR-DV-BASIC-SERV-TAX-AMT-T>
<MIR-DV-TOTL-SW-CESS-AMT-T></MIR-DV-TOTL-SW-CESS-AMT-T>
<MIR-DV-KR-KL-CESS-AMT-T></MIR-DV-KR-KL-CESS-AMT-T>
<MIR-DV-PREM-AMT-T></MIR-DV-PREM-AMT-T>
</GROUP-2>
<GROUP-3>
<MIR-DV-DUE-DT-T></MIR-DV-DUE-DT-T>
<MIR-DV-POL-MPREM-AMT-T></MIR-DV-POL-MPREM-AMT-T>
<MIR-DV-BASIC-SERV-TAX-AMT-T></MIR-DV-BASIC-SERV-TAX-AMT-T>
<MIR-DV-TOTL-SW-CESS-AMT-T></MIR-DV-TOTL-SW-CESS-AMT-T>
<MIR-DV-KR-KL-CESS-AMT-T></MIR-DV-KR-KL-CESS-AMT-T>
<MIR-DV-PREM-AMT-T></MIR-DV-PREM-AMT-T>
</GROUP-3>
<MIR-DV-ADV-PREM-AMT>1000</MIR-DV-ADV-PREM-AMT>
<MIR-TOTL-SW-BH-CESS-TAX-AMT>1000</MIR-TOTL-SW-BH-CESS-TAX-AMT>
<MIR-KR-KL-CESS-TAX-AMT>1000</MIR-KR-KL-CESS-TAX-AMT>
</OUTPUT>
</base:callFlowResponse>
</S:Body>
</S:Envelope>
我见过各种在分散的节点上进行分组的例子。但是我的要求是不同的。我有六个表,其中所有相关值都像数组一样给出。我必须逐个元素地阅读所有六个表并创建一个组。我应该这样做直到读取所有节点(在这种情况下,大小为三)
如果你能至少指导我一个类似的例子,我可以参考我的编码,那将是一个很大的帮助。
感谢您的帮助。
这是一个示例,它处理第一个 "table" 个子元素并收集每个组包装器元素中的同级 table 个子元素:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OUTPUT/*[*[starts-with(local-name(), 'Table')]][1]">
<xsl:apply-templates select="*/*" mode="group"/>
</xsl:template>
<xsl:template match="OUTPUT/*[*[starts-with(local-name(), 'Table')]][position() gt 1]"/>
<xsl:template match="*" mode="group">
<xsl:variable name="pos" select="position()"/>
<xsl:element name="group-{position()}">
<xsl:copy-of select="., ../../following-sibling::*[*[starts-with(local-name(), 'Table')]]/*/*[$pos]"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
作为收集兄弟元素的替代方法,您可以使用位置分组:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OUTPUT">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="boolean(self::*[*[starts-with(local-name(), 'Table')]])">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:variable name="row-count" select="count(*[1]/*)"/>
<xsl:for-each-group select="current-group()/*/*" group-by="position() mod $row-count">
<xsl:element name="GROUP-{position()}">
<xsl:copy-of select="current-group()"/>
</xsl:element>
</xsl:for-each-group>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我已经在下面的转换代码中工作了很长时间。我不确定该要求在 XSLT 中是否可行,需要您的帮助来确定是否可以使用 XSLT。
我的输入XML如下,
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<base:callFlowResponse xmlns:base="http://schema/webservices.elink.solcorp.com">
<Messages>
<More/>
</Messages>
<OUTPUT>
<MIR-DV-INT>100</MIR-DV-INT>
<MIR-DEP-AMT>0000000000042832.50</MIR-DEP-AMT>
<MIR-DV-TOTAL-AMT-DUE>1000</MIR-DV-TOTAL-AMT-DUE>
<MIR-MAX-REM-TOP-PREM>1000</MIR-MAX-REM-TOP-PREM>
<MIR-DV-DUE-DT-G>
<TableMIR-DV-DUE-DT-T>
<MIR-DV-DUE-DT-T>2011-01-01</MIR-DV-DUE-DT-T>
<MIR-DV-DUE-DT-T/>
<MIR-DV-DUE-DT-T/>
</TableMIR-DV-DUE-DT-T>
</MIR-DV-DUE-DT-G>
<MIR-DV-POL-MPREM-AMT-G>
<TableMIR-DV-POL-MPREM-AMT-T>
<MIR-DV-POL-MPREM-AMT-T>1000</MIR-DV-POL-MPREM-AMT-T>
<MIR-DV-POL-MPREM-AMT-T/>
<MIR-DV-POL-MPREM-AMT-T/>
</TableMIR-DV-POL-MPREM-AMT-T>
</MIR-DV-POL-MPREM-AMT-G>
<MIR-DV-BASIC-SERV-TAX-AMT-G>
<TableMIR-DV-BASIC-SERV-TAX-AMT-T>
<MIR-DV-BASIC-SERV-TAX-AMT-T>10000</MIR-DV-BASIC-SERV-TAX-AMT-T>
<MIR-DV-BASIC-SERV-TAX-AMT-T/>
<MIR-DV-BASIC-SERV-TAX-AMT-T/>
</TableMIR-DV-BASIC-SERV-TAX-AMT-T>
</MIR-DV-BASIC-SERV-TAX-AMT-G>
<MIR-DV-TOTL-SW-CESS-AMT-G>
<TableMIR-DV-TOTL-SW-CESS-AMT-T>
<MIR-DV-TOTL-SW-CESS-AMT-T>1000</MIR-DV-TOTL-SW-CESS-AMT-T>
<MIR-DV-TOTL-SW-CESS-AMT-T/>
<MIR-DV-TOTL-SW-CESS-AMT-T/>
</TableMIR-DV-TOTL-SW-CESS-AMT-T>
</MIR-DV-TOTL-SW-CESS-AMT-G>
<MIR-DV-KR-KL-CESS-AMT-G>
<TableMIR-DV-KR-KL-CESS-AMT-T>
<MIR-DV-KR-KL-CESS-AMT-T>1000</MIR-DV-KR-KL-CESS-AMT-T>
<MIR-DV-KR-KL-CESS-AMT-T/>
<MIR-DV-KR-KL-CESS-AMT-T/>
</TableMIR-DV-KR-KL-CESS-AMT-T>
</MIR-DV-KR-KL-CESS-AMT-G>
<MIR-DV-PREM-AMT-G>
<TableMIR-DV-PREM-AMT-T>
<MIR-DV-PREM-AMT-T>10000</MIR-DV-PREM-AMT-T>
<MIR-DV-PREM-AMT-T/>
<MIR-DV-PREM-AMT-T/>
</TableMIR-DV-PREM-AMT-T>
</MIR-DV-PREM-AMT-G>
<MIR-DV-ADV-PREM-AMT>1000</MIR-DV-ADV-PREM-AMT>
<MIR-TOTL-SW-BH-CESS-TAX-AMT>1000</MIR-TOTL-SW-BH-CESS-TAX-AMT>
<MIR-KR-KL-CESS-TAX-AMT>1000</MIR-KR-KL-CESS-TAX-AMT>
</OUTPUT>
</base:callFlowResponse>
</S:Body>
</S:Envelope>
输出 XML 应该是,
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<base:callFlowResponse xmlns:base="http://schema/webservices.elink.solcorp.com">
<Messages>
<More/>
</Messages>
<OUTPUT>
<MIR-DV-INT>100</MIR-DV-INT>
<MIR-DEP-AMT>0000000000042832.50</MIR-DEP-AMT>
<MIR-DV-TOTAL-AMT-DUE>1000</MIR-DV-TOTAL-AMT-DUE>
<MIR-MAX-REM-TOP-PREM>1000</MIR-MAX-REM-TOP-PREM>
<GROUP-1>
<MIR-DV-DUE-DT-T>2011-01-01</MIR-DV-DUE-DT-T>
<MIR-DV-POL-MPREM-AMT-T>1000</MIR-DV-POL-MPREM-AMT-T>
<MIR-DV-BASIC-SERV-TAX-AMT-T>10000</MIR-DV-BASIC-SERV-TAX-AMT-T>
<MIR-DV-TOTL-SW-CESS-AMT-T>1000</MIR-DV-TOTL-SW-CESS-AMT-T>
<MIR-DV-KR-KL-CESS-AMT-T>1000</MIR-DV-KR-KL-CESS-AMT-T>
<MIR-DV-PREM-AMT-T>10000</MIR-DV-PREM-AMT-T>
</GROUP-1>
<GROUP-2>
<MIR-DV-DUE-DT-T></MIR-DV-DUE-DT-T>
<MIR-DV-POL-MPREM-AMT-T></MIR-DV-POL-MPREM-AMT-T>
<MIR-DV-BASIC-SERV-TAX-AMT-T></MIR-DV-BASIC-SERV-TAX-AMT-T>
<MIR-DV-TOTL-SW-CESS-AMT-T></MIR-DV-TOTL-SW-CESS-AMT-T>
<MIR-DV-KR-KL-CESS-AMT-T></MIR-DV-KR-KL-CESS-AMT-T>
<MIR-DV-PREM-AMT-T></MIR-DV-PREM-AMT-T>
</GROUP-2>
<GROUP-3>
<MIR-DV-DUE-DT-T></MIR-DV-DUE-DT-T>
<MIR-DV-POL-MPREM-AMT-T></MIR-DV-POL-MPREM-AMT-T>
<MIR-DV-BASIC-SERV-TAX-AMT-T></MIR-DV-BASIC-SERV-TAX-AMT-T>
<MIR-DV-TOTL-SW-CESS-AMT-T></MIR-DV-TOTL-SW-CESS-AMT-T>
<MIR-DV-KR-KL-CESS-AMT-T></MIR-DV-KR-KL-CESS-AMT-T>
<MIR-DV-PREM-AMT-T></MIR-DV-PREM-AMT-T>
</GROUP-3>
<MIR-DV-ADV-PREM-AMT>1000</MIR-DV-ADV-PREM-AMT>
<MIR-TOTL-SW-BH-CESS-TAX-AMT>1000</MIR-TOTL-SW-BH-CESS-TAX-AMT>
<MIR-KR-KL-CESS-TAX-AMT>1000</MIR-KR-KL-CESS-TAX-AMT>
</OUTPUT>
</base:callFlowResponse>
</S:Body>
</S:Envelope>
我见过各种在分散的节点上进行分组的例子。但是我的要求是不同的。我有六个表,其中所有相关值都像数组一样给出。我必须逐个元素地阅读所有六个表并创建一个组。我应该这样做直到读取所有节点(在这种情况下,大小为三)
如果你能至少指导我一个类似的例子,我可以参考我的编码,那将是一个很大的帮助。
感谢您的帮助。
这是一个示例,它处理第一个 "table" 个子元素并收集每个组包装器元素中的同级 table 个子元素:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OUTPUT/*[*[starts-with(local-name(), 'Table')]][1]">
<xsl:apply-templates select="*/*" mode="group"/>
</xsl:template>
<xsl:template match="OUTPUT/*[*[starts-with(local-name(), 'Table')]][position() gt 1]"/>
<xsl:template match="*" mode="group">
<xsl:variable name="pos" select="position()"/>
<xsl:element name="group-{position()}">
<xsl:copy-of select="., ../../following-sibling::*[*[starts-with(local-name(), 'Table')]]/*/*[$pos]"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
作为收集兄弟元素的替代方法,您可以使用位置分组:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* , node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OUTPUT">
<xsl:copy>
<xsl:for-each-group select="*" group-adjacent="boolean(self::*[*[starts-with(local-name(), 'Table')]])">
<xsl:choose>
<xsl:when test="current-grouping-key()">
<xsl:variable name="row-count" select="count(*[1]/*)"/>
<xsl:for-each-group select="current-group()/*/*" group-by="position() mod $row-count">
<xsl:element name="GROUP-{position()}">
<xsl:copy-of select="current-group()"/>
</xsl:element>
</xsl:for-each-group>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="current-group()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>