根据 xslt 中的一个元素对 xml 条包含所需子元素的记录进行分组
Grouping xml recordswith required child elements based on one element in xslt
我正在尝试根据一个字段在剩余记录中具有相同数据的条件对 XML 条记录进行分组。我们将收到包含文档编号的 A_ROW 详细信息,我已将 B_ROW 记录分组到具有相同文档编号的 A_ROW 下。任何人都可以帮助阅读和分组 xslt 中的 xml 记录。
<recordSet>
<A_Row><company_code>1234</company_code>
<document_num>5606</document_num>
<document_type>CS</document_type>
<doc_date>20190206</doc_date>
</A_Row>
<B_Row>
<document_num>5606</document_num>
<pos>001</pos>
<account>4564343</account>
<account_type>ss</account_type>
</B_Row>
<B_Row>
<document_num>5606</document_num>
<pos>001</pos>
<account>4564344</account>
<account_type>ss</account_type>
</B_Row>
<A_Row><company_code>1234</company_code>
<document_num>5607</document_num>
<document_type>CS</document_type>
<doc_date>20190206</doc_date>
</A_Row>
<B_Row>
<document_num>5607</document_num>
<pos>001</pos>
<account>4564346</account>
<account_type>ss</account_type>
</B_Row>
<B_Row>
<document_num>5607</document_num>
<pos>001</pos>
<account>4564342</account>
<account_type>ss</account_type>
</B_Row>
<A_Row>
<company_code>1234</company_code>
<document_num>5608</document_num>
<document_type>CS</document_type>
<doc_date>20190206</doc_date>
</A_Row>
<B_Row>
<document_num>5608</document_num>
<pos>001</pos>
<account>4564349</account>
<account_type>ss</account_type>
</B_Row>
</recordSet>
XSLT 代码:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ns="http://springer.com/xi/SAP/MEDIASUITE">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Recordset">
<xsl:for-each select="BT_ROW">
<xsl:element name="BT_ROW">
<xsl:apply-templates/>
<xsl:variable name="document" select="/ns:MT_MEDIASUITE_ORDER_DATA/Recordset/BT_ROW/document_number"/>
<xsl:for-each select="/ns:MT_MEDIASUITE_ORDER_DATA/Recordset/BS_ROW">
<xsl:if test="/ns:MT_MEDIASUITE_ORDER_DATA/Recordset/BS_ROW/document_number =$document">
<xsl:element name="BS_ROW">
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
预期结果:
<recordSet>
<A_Row><company_code>1234</company_code>
<document_num>5606</document_num>
<document_type>CS</document_type>
<doc_date>20190206</doc_date>
<B_Row>
<document_num>5606</document_num>
<pos>001</pos>
<account>4564343</account>
<account_type>ss</account_type>
</B_Row>
<B_Row>
<document_num>5606</document_num>
<pos>001</pos>
<account>4564344</account>
<account_type>ss</account_type>
</B_Row>
</A_Row>
<A_Row>
<company_code>1234</company_code>
<document_num>5607</document_num>
<document_type>CS</document_type>
<doc_date>20190206</doc_date>
<B_Row>
<document_num>5607</document_num>
<pos>001</pos>
<account>4564346</account>
<account_type>ss</account_type>
</B_Row>
<B_Row>
<document_num>5607</document_num>
<pos>001</pos>
<account>4564342</account>
<account_type>ss</account_type>
</B_Row>
</A_Row>
<A_Row>
<company_code>1234</company_code>
<document_num>5608</document_num>
<document_type>CS</document_type>
<doc_date>20190206</doc_date>
<B_Row>
<document_num>5608</document_num>
<pos>001</pos>
<account>4564349</account>
<account_type>ss</account_type>
</B_Row>
</A_Row>
</recordSet>
对于每个 "group" 似乎都以 A_Row
开头的输入样本,使用 group-by
和浅复制第一个项目就足够了,然后用它的子项填充它,团尾:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="recordSet">
<xsl:copy>
<xsl:for-each-group select="*" group-by="document_num">
<xsl:copy>
<xsl:apply-templates select="node(), tail(current-group())"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我使用了下面的代码,效果很好
<xsl:element name="A_ROW">
<xsl:apply-templates/>
<xsl:variable name="doc_num" select="document_number"/>
<xsl:variable name="pos1" select="fn:position()"/>
<xsl:for-each select="//B_ROW">
<xsl:variable name="pos" select="fn:position()"/>
<xsl:if test="//B_ROW[$pos]/document_number=$doc_num">
<xsl:element name="BS_ROW">
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
我正在尝试根据一个字段在剩余记录中具有相同数据的条件对 XML 条记录进行分组。我们将收到包含文档编号的 A_ROW 详细信息,我已将 B_ROW 记录分组到具有相同文档编号的 A_ROW 下。任何人都可以帮助阅读和分组 xslt 中的 xml 记录。
<recordSet>
<A_Row><company_code>1234</company_code>
<document_num>5606</document_num>
<document_type>CS</document_type>
<doc_date>20190206</doc_date>
</A_Row>
<B_Row>
<document_num>5606</document_num>
<pos>001</pos>
<account>4564343</account>
<account_type>ss</account_type>
</B_Row>
<B_Row>
<document_num>5606</document_num>
<pos>001</pos>
<account>4564344</account>
<account_type>ss</account_type>
</B_Row>
<A_Row><company_code>1234</company_code>
<document_num>5607</document_num>
<document_type>CS</document_type>
<doc_date>20190206</doc_date>
</A_Row>
<B_Row>
<document_num>5607</document_num>
<pos>001</pos>
<account>4564346</account>
<account_type>ss</account_type>
</B_Row>
<B_Row>
<document_num>5607</document_num>
<pos>001</pos>
<account>4564342</account>
<account_type>ss</account_type>
</B_Row>
<A_Row>
<company_code>1234</company_code>
<document_num>5608</document_num>
<document_type>CS</document_type>
<doc_date>20190206</doc_date>
</A_Row>
<B_Row>
<document_num>5608</document_num>
<pos>001</pos>
<account>4564349</account>
<account_type>ss</account_type>
</B_Row>
</recordSet>
XSLT 代码:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ns="http://springer.com/xi/SAP/MEDIASUITE">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Recordset">
<xsl:for-each select="BT_ROW">
<xsl:element name="BT_ROW">
<xsl:apply-templates/>
<xsl:variable name="document" select="/ns:MT_MEDIASUITE_ORDER_DATA/Recordset/BT_ROW/document_number"/>
<xsl:for-each select="/ns:MT_MEDIASUITE_ORDER_DATA/Recordset/BS_ROW">
<xsl:if test="/ns:MT_MEDIASUITE_ORDER_DATA/Recordset/BS_ROW/document_number =$document">
<xsl:element name="BS_ROW">
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
预期结果:
<recordSet>
<A_Row><company_code>1234</company_code>
<document_num>5606</document_num>
<document_type>CS</document_type>
<doc_date>20190206</doc_date>
<B_Row>
<document_num>5606</document_num>
<pos>001</pos>
<account>4564343</account>
<account_type>ss</account_type>
</B_Row>
<B_Row>
<document_num>5606</document_num>
<pos>001</pos>
<account>4564344</account>
<account_type>ss</account_type>
</B_Row>
</A_Row>
<A_Row>
<company_code>1234</company_code>
<document_num>5607</document_num>
<document_type>CS</document_type>
<doc_date>20190206</doc_date>
<B_Row>
<document_num>5607</document_num>
<pos>001</pos>
<account>4564346</account>
<account_type>ss</account_type>
</B_Row>
<B_Row>
<document_num>5607</document_num>
<pos>001</pos>
<account>4564342</account>
<account_type>ss</account_type>
</B_Row>
</A_Row>
<A_Row>
<company_code>1234</company_code>
<document_num>5608</document_num>
<document_type>CS</document_type>
<doc_date>20190206</doc_date>
<B_Row>
<document_num>5608</document_num>
<pos>001</pos>
<account>4564349</account>
<account_type>ss</account_type>
</B_Row>
</A_Row>
</recordSet>
对于每个 "group" 似乎都以 A_Row
开头的输入样本,使用 group-by
和浅复制第一个项目就足够了,然后用它的子项填充它,团尾:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="recordSet">
<xsl:copy>
<xsl:for-each-group select="*" group-by="document_num">
<xsl:copy>
<xsl:apply-templates select="node(), tail(current-group())"/>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我使用了下面的代码,效果很好
<xsl:element name="A_ROW">
<xsl:apply-templates/>
<xsl:variable name="doc_num" select="document_number"/>
<xsl:variable name="pos1" select="fn:position()"/>
<xsl:for-each select="//B_ROW">
<xsl:variable name="pos" select="fn:position()"/>
<xsl:if test="//B_ROW[$pos]/document_number=$doc_num">
<xsl:element name="BS_ROW">
<xsl:apply-templates/>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>