xml - 需要将所有兄弟姐妹的 XML 文档转换为带有父/子组的 XML
问题描述
我是 XSLT 的新手。我有一个从 Web 服务返回的 XML 响应文档,其中包含每个后缀的标头 (Result_HEADER) 以及标头下方该后缀的事务详细信息(Result_Y 和 Result_Addendum)。标头和事务元素都在响应 XML 中作为同级元素。这是原始的 XML:
<?xml version="1.0" encoding="UTF-8"?>
<Peak mlns="http://peak.company.com"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<OffTime>
<CommandRs>
<ResponseHeader>
<Status>
<StatusCode>00</StatusCode>
<StatusDesc>SUCCESSFUL</StatusDesc>
</Status>
</ResponseHeader>
<AHINRs>
<Result_HEADER>
<Identifier>HEADER</Identifier>
<Account>11111111</Account>
<Suffix>0</Suffix>
<Name>JohnDoe</Name>
<FinancialInstitutionDt>44444444</FinancialInstitutionDt>
<BranchID>3</BranchID>
</Result_HEADER>
<Identifier>HEADER</Identifier>
<Account>11111111</Account>
<Suffix>0</Suffix>
<Name>JohnDoe</Name>
<FinancialInstitutionDt>44444444</FinancialInstitutionDt>
<BranchID>3</BranchID>
</Result_HEADER>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2734</ID>
<BatchID>0312</BatchID>
<TraceID>6355577</TraceID>
<EffectiveDt>20180411</EffectiveDt>
<PostingCode>DS</PostingCode>
<TransactionType>AE</TransactionType>
<Amount>-45400</Amount>
<Group>8888</Group>
<Command>ACHP</Command>
<ReturnCode />
<Status>POSTED</Status>
<TypeCode>RC</TypeCode>
<CompanyName>USAA.COM PAYMNT</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>CREDIT CRD</Description>
</Result_Y>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2735</ID>
<BatchID>0312</BatchID>
<TraceID>6355577</TraceID>
<EffectiveDt>20180411</EffectiveDt>
<PostingCode>DS</PostingCode>
<TransactionType>AE</TransactionType>
<Amount>-45400</Amount>
<Group>8888</Group>
<Command>ACHP</Command>
<ReturnCode />
<Status>POSTED</Status>
<TypeCode>RC</TypeCode>
<CompanyName>USAA.COM PAYMNT</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>CREDIT CRD</Description>
</Result_Y>
<Result_HEADER>
<Identifier>HEADER</Identifier>
<Account>11111111</Account>
<Suffix>2</Suffix>
<Name>JohnDoe</Name>
<FinancialInstitutionDt>44444444</FinancialInstitutionDt>
<BranchID>3</BranchID>
</Result_HEADER>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2687</ID>
<BatchID>0207</BatchID>
<TraceID>3362157</TraceID>
<EffectiveDt>020180301</EffectiveDt>
<PostingCode>PA</PostingCode>
<TransactionType />
<Amount>93741</Amount>
<Group>1017</Group>
<Command>PTDD</Command>
<ReturnCode />
<Status>PENDING</Status>
<TypeCode>RC</TypeCode>
<CompanyName>VACP TREAS 310</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>XXVA BENEF</Description>
</Result_Y>
<Result_ARADDENDUM>
<OutputType>ARADDENDUM</OutputType>
<ACHAddendum>REF*48*VA COMPENSATION *02/01/18-02/28/18 \</ACHAddendum>
</Result_ARADDENDUM>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2695</ID>
<BatchID>0646</BatchID>
<TraceID>0144778</TraceID>
<EffectiveDt>20180301</EffectiveDt>
<PostingCode>PA</PostingCode>
<TransactionType />
<Amount>236594</Amount>
<Group>1014</Group>
<Command>PTDD</Command>
<ReturnCode />
<Status>PENDING</Status>
<TypeCode>RC</TypeCode>
<CompanyName>DFAS-CLEVELAND</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>RET NET</Description>
</Result_Y>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2725</ID>
<BatchID>0597</BatchID>
<TraceID>3366249</TraceID>
<EffectiveDt>20180330</EffectiveDt>
<PostingCode>PA</PostingCode>
<TransactionType />
<Amount>93741</Amount>
<Group>1017</Group>
<Command>PTDD</Command>
<ReturnCode />
<Status>PENDING</Status>
<TypeCode>RC</TypeCode>
<CompanyName>VACP TREAS 310</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>XXVA BENEF</Description>
</Result_Y>
<Result_ARADDENDUM>
<OutputType>ARADDENDUM</OutputType>
<ACHAddendum>REF*48*VA COMPENSATION *03/01/18-03/31/18 \</ACHAddendum>
</Result_ARADDENDUM>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2734</ID>
<BatchID>0312</BatchID>
<TraceID>6355577</TraceID>
<EffectiveDt>20180411</EffectiveDt>
<PostingCode>DS</PostingCode>
<TransactionType>AE</TransactionType>
<Amount>-45400</Amount>
<Group>8888</Group>
<Command>ACHP</Command>
<ReturnCode />
<Status>POSTED</Status>
<TypeCode>RC</TypeCode>
<CompanyName>USAA.COM PAYMNT</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>CREDIT CRD</Description>
</Result_Y>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2735</ID>
<BatchID>0312</BatchID>
<TraceID>6355577</TraceID>
<EffectiveDt>20180411</EffectiveDt>
<PostingCode>DS</PostingCode>
<TransactionType>AE</TransactionType>
<Amount>-45400</Amount>
<Group>8888</Group>
<Command>ACHP</Command>
<ReturnCode />
<Status>POSTED</Status>
<TypeCode>RC</TypeCode>
<CompanyName>USAA.COM PAYMNT</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>CREDIT CRD</Description>
</Result_Y>
<Result_HEADER>
<Identifier>HEADER</Identifier>
<Account>11111111</Account>
<Suffix>3</Suffix>
<Name>JohnDoe</Name>
<FinancialInstitutionDt>44444444</FinancialInstitutionDt>
<BranchID>3</BranchID>
</Result_HEADER>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2732</ID>
<BatchID>0911</BatchID>
<TraceID>6314883</TraceID>
<EffectiveDt>20180403</EffectiveDt>
<PostingCode>DS</PostingCode>
<TransactionType>AE</TransactionType>
<Amount>-18638</Amount>
<Group>8888</Group>
<Command>ACHP</Command>
<ReturnCode />
<Status>PENDING</Status>
<TypeCode>RC</TypeCode>
<CompanyName>VERIZON</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>PAYMENTREC</Description>
</Result_Y>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2732</ID>
<BatchID>1751</BatchID>
<TraceID>3553385</TraceID>
<EffectiveDt>20180403</EffectiveDt>
<PostingCode>PA</PostingCode>
<TransactionType />
<Amount>119391</Amount>
<Group>8888</Group>
<Command>PTDD</Command>
<ReturnCode />
<Status>PENDING</Status>
<TypeCode>RC</TypeCode>
<CompanyName>CONCUR</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>EXPENSE</Description>
</Result_Y>
<Result_ARADDENDUM>
<OutputType>ARADDENDUM</OutputType>
<ACHAddendum>Flight home for Ethridge</ACHAddendum>
</Result_ARADDENDUM>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2732</ID>
<BatchID>1751</BatchID>
<TraceID>3553387</TraceID>
<EffectiveDt>20180403</EffectiveDt>
<PostingCode>PA</PostingCode>
<TransactionType />
<Amount>61500</Amount>
<Group>8888</Group>
<Command>PTDD</Command>
<ReturnCode />
<Status>PENDING</Status>
<TypeCode>RC</TypeCode>
<CompanyName>CONCUR</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>EXPENSE</Description>
</Result_Y>
<Result_ARADDENDUM>
<OutputType>ARADDENDUM</OutputType>
<ACHAddendum>Flight to CRC to Williams</ACHAddendum>
</Result_ARADDENDUM>
</AHINRs>
</CommandRs>
</OffTime>
</Peak>
我需要能够重组文档,以便每个 Header 元素都包含一个 Results 元素,其中包含该标头的事务详细信息,这里是所需的 XML:
<?xml version="1.0" encoding="UTF-8"?>
<Peak xmlns="http://peak.company.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<OffTime>
<CommandRs>
<ResponseHeader>
<Status>
<StatusCode>00</StatusCode>
<StatusDesc>SUCCESSFUL</StatusDesc>
</Status>
</ResponseHeader>
<AHINRs>
<Result_HEADER>
<Identifier>HEADER</Identifier>
<Account>11111111</Account>
<Suffix>0</Suffix>
<Name>JohnDoe</Name>
<FinancialInstitutionDt>44444444</FinancialInstitutionDt>
<BranchID>3</BranchID>
<Results>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2734</ID>
<BatchID>0312</BatchID>
<TraceID>6355577</TraceID>
<EffectiveDt>20180411</EffectiveDt>
<PostingCode>DS</PostingCode>
<TransactionType>AE</TransactionType>
<Amount>-45400</Amount>
<Group>8888</Group>
<Command>ACHP</Command>
<ReturnCode />
<Status>POSTED</Status>
<TypeCode>RC</TypeCode>
<CompanyName>USAA.COM PAYMNT</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>CREDIT CRD</Description>
</Result_Y>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2735</ID>
<BatchID>0312</BatchID>
<TraceID>6355577</TraceID>
<EffectiveDt>20180411</EffectiveDt>
<PostingCode>DS</PostingCode>
<TransactionType>AE</TransactionType>
<Amount>-45400</Amount>
<Group>8888</Group>
<Command>ACHP</Command>
<ReturnCode />
<Status>POSTED</Status>
<TypeCode>RC</TypeCode>
<CompanyName>USAA.COM PAYMNT</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>CREDIT CRD</Description>
</Result_Y>
</Results>
</Result_HEADER>
<Result_HEADER>
<Identifier>HEADER</Identifier>
<Account>11111111</Account>
<Suffix>2</Suffix>
<Name>JohnDoe</Name>
<FinancialInstitutionDt>44444444</FinancialInstitutionDt>
<BranchID>3</BranchID>
</Results>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2687</ID>
<BatchID>0207</BatchID>
<TraceID>3362157</TraceID>
<EffectiveDt>020180301</EffectiveDt>
<PostingCode>PA</PostingCode>
<TransactionType />
<Amount>93741</Amount>
<Group>1017</Group>
<Command>PTDD</Command>
<ReturnCode />
<Status>PENDING</Status>
<TypeCode>RC</TypeCode>
<CompanyName>VACP TREAS 310</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>XXVA BENEF</Description>
</Result_Y>
<Result_ARADDENDUM>
<OutputType>ARADDENDUM</OutputType>
<ACHAddendum>REF*48*VA COMPENSATION *02/01/18-02/28/18 \</ACHAddendum>
</Result_ARADDENDUM>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2695</ID>
<BatchID>0646</BatchID>
<TraceID>0144778</TraceID>
<EffectiveDt>20180301</EffectiveDt>
<PostingCode>PA</PostingCode>
<TransactionType />
<Amount>236594</Amount>
<Group>1014</Group>
<Command>PTDD</Command>
<ReturnCode />
<Status>PENDING</Status>
<TypeCode>RC</TypeCode>
<CompanyName>DFAS-CLEVELAND</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>RET NET</Description>
</Result_Y>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2725</ID>
<BatchID>0597</BatchID>
<TraceID>3366249</TraceID>
<EffectiveDt>20180330</EffectiveDt>
<PostingCode>PA</PostingCode>
<TransactionType />
<Amount>93741</Amount>
<Group>1017</Group>
<Command>PTDD</Command>
<ReturnCode />
<Status>PENDING</Status>
<TypeCode>RC</TypeCode>
<CompanyName>VACP TREAS 310</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>XXVA BENEF</Description>
</Result_Y>
<Result_ARADDENDUM>
<OutputType>ARADDENDUM</OutputType>
<ACHAddendum>REF*48*VA COMPENSATION *03/01/18-03/31/18 \</ACHAddendum>
</Result_ARADDENDUM>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2734</ID>
<BatchID>0312</BatchID>
<TraceID>6355577</TraceID>
<EffectiveDt>20180411</EffectiveDt>
<PostingCode>DS</PostingCode>
<TransactionType>AE</TransactionType>
<Amount>-45400</Amount>
<Group>8888</Group>
<Command>ACHP</Command>
<ReturnCode />
<Status>POSTED</Status>
<TypeCode>RC</TypeCode>
<CompanyName>USAA.COM PAYMNT</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>CREDIT CRD</Description>
</Result_Y>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2735</ID>
<BatchID>0312</BatchID>
<TraceID>6355577</TraceID>
<EffectiveDt>20180411</EffectiveDt>
<PostingCode>DS</PostingCode>
<TransactionType>AE</TransactionType>
<Amount>-45400</Amount>
<Group>8888</Group>
<Command>ACHP</Command>
<ReturnCode />
<Status>POSTED</Status>
<TypeCode>RC</TypeCode>
<CompanyName>USAA.COM PAYMNT</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>CREDIT CRD</Description>
</Result_Y>
</Results>
</Result_HEADER>
<Result_HEADER>
<Identifier>HEADER</Identifier>
<Account>11111111</Account>
<Suffix>3</Suffix>
<Name>JohnDoe</Name>
<FinancialInstitutionDt>44444444</FinancialInstitutionDt>
<BranchID>3</BranchID>
<Results>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2732</ID>
<BatchID>0911</BatchID>
<TraceID>6314883</TraceID>
<EffectiveDt>20180403</EffectiveDt>
<PostingCode>DS</PostingCode>
<TransactionType>AE</TransactionType>
<Amount>-18638</Amount>
<Group>8888</Group>
<Command>ACHP</Command>
<ReturnCode />
<Status>PENDING</Status>
<TypeCode>RC</TypeCode>
<CompanyName>VERIZON</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>PAYMENTREC</Description>
</Result_Y>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2732</ID>
<BatchID>1751</BatchID>
<TraceID>3553385</TraceID>
<EffectiveDt>20180403</EffectiveDt>
<PostingCode>PA</PostingCode>
<TransactionType />
<Amount>119391</Amount>
<Group>8888</Group>
<Command>PTDD</Command>
<ReturnCode />
<Status>PENDING</Status>
<TypeCode>RC</TypeCode>
<CompanyName>CONCUR</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>EXPENSE</Description>
</Result_Y>
<Result_ARADDENDUM>
<OutputType>ARADDENDUM</OutputType>
<ACHAddendum>Flight home for Ethridge</ACHAddendum>
</Result_ARADDENDUM>
<Result_Y>
<DetailFlag>Y</DetailFlag>
<ID>2732</ID>
<BatchID>1751</BatchID>
<TraceID>3553387</TraceID>
<EffectiveDt>20180403</EffectiveDt>
<PostingCode>PA</PostingCode>
<TransactionType />
<Amount>61500</Amount>
<Group>8888</Group>
<Command>PTDD</Command>
<ReturnCode />
<Status>PENDING</Status>
<TypeCode>RC</TypeCode>
<CompanyName>CONCUR</CompanyName>
<CompanyID>1234567890</CompanyID>
<Description>EXPENSE</Description>
</Result_Y>
<Result_ARADDENDUM>
<OutputType>ARADDENDUM</OutputType>
<ACHAddendum>Flight to CRC to Williams</ACHAddendum>
</Result_ARADDENDUM>
</Results>
</Result_HEADER>
</AHINRs>
</CommandRs>
</OffTime>
</Peak>
我已经能够使用显示的 XSL 创建标题并将结果元素添加到每个标题。我无法弄清楚如何在正确的结果元素中选择和插入属于每个标题的事务作为子项:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:fn="http://peak.company.com" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="fn:Peak"/>
</xsl:template>
<xsl:template match="fn:Peak">
<xsl:copy select=".">
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="fn:OffTime"/>
</xsl:copy>
</xsl:template>
<xsl:template match="fn:OffTime">
<xsl:copy select=".">
<xsl:apply-templates select="fn:CommandRs"/>
</xsl:copy>
</xsl:template>
<xsl:template match="fn:CommandRs">
<xsl:copy select=".">
<xsl:apply-templates select="fn:ResponseHeader"/>
<xsl:apply-templates select="fn:AHINRs"/>
</xsl:copy>
</xsl:template>
<xsl:template match="fn:ResponseHeader">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="fn:AHINRs">
<xsl:copy select=".">
<xsl:apply-templates select="fn:Result_HEADER"/>
</xsl:copy>
</xsl:template>
<xsl:template match="fn:Result_HEADER">
<xsl:if test="position() = last()">
<xsl:call-template name="copy-children"/>
<xsl:element name="Results" namespace="http://peak.company.com"/>
</xsl:if>
<xsl:if test="position() != last()">
<xsl:call-template name="copy-children"/>
<xsl:element name="Results" namespace="http://peak.company.com"/>
</xsl:if>
</xsl:template>
<!-- Copy the children of the current node. -->
<xsl:template name="copy-children">
<xsl:copy-of select="./*"/>
</xsl:template>
</xsl:stylesheet>
帮助将不胜感激!
解决方案
我认为,假设 XSLT 2 或 3,您希望xsl:for-each-group select="*" group-starting-with="Result_HEADER"
在模板匹配的上下文中应用AHINRs
:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="AHINRs">
<xsl:copy>
<xsl:for-each-group select="*" group-starting-with="Result_HEADER">
<xsl:copy>
<xsl:apply-templates/>
<Results>
<xsl:apply-templates select="current-group() except ."/>
</Results>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/bFDb2BW有一个工作演示,如果您与 XSLT 2 相关联,请将其替换xsl:mode
为身份转换模板。
同样仔细观察,您的元素似乎应该位于该名称空间中(尽管发布的示例没有正确的名称空间声明),因此在您的真实代码中,您可能希望使用 XSLT 启动
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
xpath-default-namespace="http://peak.company.com"
xmlns="http://peak.company.com"
version="3.0">
考虑命名空间。
推荐阅读
- android - Flutter插件的UI测试
- c# - How to flag files/folder as not in solution with DotNetCore projects?
- python - 熊猫合并:内存错误:
- jenkins - 收到语法错误:“(”在我的 Jenkins 文件中出现意外(groovy)
- c - PIC18FXXXXX UART Tx 消息功能?
- python - 如何使用熊猫绘制时间序列数据的直方图?
- java - 不试就抓住
- wordpress - 更新 Woocommerce 订阅订单项元数据
- gcc - 使用cmake时如何将VS2017指向(arm-none-eabi-)gcc默认标头
- java - 如何在 GET 请求中排除其他类对象?- Java 春季启动