我使用XSLT验证文档,但它没有按照我预期的方式工作。
我有一个XML文档,其中每个LodgementInstructions
或LodgementDocument
都有一对Counterparts
,其中每个都有一组InvolvedParties
。我想确保每个'对应的'我基于InvolvedParties
拥有相同的PartyId
,因此这是我的计划:对于每个LodgementDocument
或LodgementInstructions
,请获取所有InvolvedParties
的一组Counterparts
全部$setOfAllCounterpartPartyIds
,Counterpart
。然后,针对每个$setOfAllCounterpartPartyIds
比较PartyId
,将$partyIdsForThisCounterpart
s用于该对应项,<SemanticErrors xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
document IDs
LI1402992691249
Counterpart ID [CP1402992691548]
setOfAllCounterpartPartyIds = [<PartyId>1</PartyId><PartyId>2</PartyId>]
partyIdsForThisCounterpart = [<PartyId>1</PartyId><PartyId>2</PartyId>]
Are [<PartyId>1</PartyId><PartyId>2</PartyId>] and [<PartyId>1</PartyId><PartyId>2</PartyId>] the same? [true]
Counterpart ID [CP1402992694237]
setOfAllCounterpartPartyIds = [<PartyId>1</PartyId><PartyId>2</PartyId>]
partyIdsForThisCounterpart = [<PartyId>1</PartyId><PartyId>2</PartyId>]
Are [<PartyId>1</PartyId><PartyId>2</PartyId>] and [<PartyId>1</PartyId><PartyId>2</PartyId>] the same? [false]
Validation error:
Those elements that are in the first set but not the second:
<PartyId>1</PartyId><PartyId>2</PartyId>
...
。如果它们是相同的,一切都很好;如果它们不同,那么我构建一条错误消息。
但是,我看到的行为是第一个对应方通过差异测试,但第二个失败,即使节点集看起来对我来说也是如此。这是我的调试输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<LodgementVerification>
<LodgementCase>
<ElnLodgementCaseId>12345</ElnLodgementCaseId>
<LodgementInstructions>
<ElnDocumentId>LI1402992691249</ElnDocumentId>
<Counterpart>
<Counterpart>
<CounterpartData>
<ElnCounterpartId>CP1402992691548</ElnCounterpartId>
<ElnLodgementCaseId>1402986735664</ElnLodgementCaseId>
<ElnDocumentId>LI1402992691249</ElnDocumentId>
<CounterpartContent>
<LodgementInstructions>
<LodgementCaseDetail>
<DocumentCount>1</DocumentCount>
</LodgementCaseDetail>
</LodgementInstructions>
</CounterpartContent>
<InvolvedParty>
<PartyId>1</PartyId>
<PartyType>Organisation</PartyType>
</InvolvedParty>
<InvolvedParty>
<PartyId>2</PartyId>
<PartyType>Organisation</PartyType>
</InvolvedParty>
</CounterpartData>
</Counterpart>
</Counterpart>
<Counterpart>
<Counterpart>
<CounterpartData>
<ElnCounterpartId>CP1402992694237</ElnCounterpartId>
<ElnLodgementCaseId>1402986735664</ElnLodgementCaseId>
<ElnDocumentId>LI1402992691249</ElnDocumentId>
<InvolvedParty>
<PartyId>1</PartyId>
<PartyType>Organisation</PartyType>
</InvolvedParty>
<InvolvedParty>
<PartyId>2</PartyId>
<PartyType>Organisation</PartyType>
</InvolvedParty>
</CounterpartData>
</Counterpart>
</Counterpart>
</LodgementInstructions>
<DocumentCount>1</DocumentCount>
<LodgementDocument>
<ElnDocumentId>M1402987029798</ElnDocumentId>
<Counterpart>
<Counterpart>
<CounterpartData>
<ElnCounterpartId>CP1402992691501</ElnCounterpartId>
<ElnDocumentId>M1402987029798</ElnDocumentId>
<InvolvedParty>
<PartyId>1</PartyId>
<PartyType>Organisation</PartyType>
</InvolvedParty>
<InvolvedParty>
<PartyId>2</PartyId>
<PartyType>Organisation</PartyType>
</InvolvedParty>
</CounterpartData>
</Counterpart>
</Counterpart>
<Counterpart>
<Counterpart>
<CounterpartData>
<ElnCounterpartId>CP1402992691500</ElnCounterpartId>
<ElnDocumentId>M1402987029798</ElnDocumentId>
<InvolvedParty>
<PartyId>1</PartyId>
<PartyType>Organisation</PartyType>
</InvolvedParty>
<InvolvedParty>
<PartyId>2</PartyId>
<PartyType>Organisation</PartyType>
</InvolvedParty>
</CounterpartData>
</Counterpart>
</Counterpart>
</LodgementDocument>
</LodgementCase>
</LodgementVerification>
我正在使用http://exslt.org/set/index.html中的设置差异功能,但我不认为问题出在这里,因为我已经将它换掉并使用了Sal Mangano的设定操作&#39 ; s XSLT Cookbook (第1章和第9章)并得到了相同的结果。
我假设我的函数式编程思维集是歪斜的。我无法理解为什么第二次迭代时集合差异失败。任何人都可以看到我可能做错了吗?
这是XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:template match="/">
<SemanticErrors>
<xsl:for-each select="//LodgementInstructions | //LodgementDocument">
<xsl:variable name="elnDocumentId" select="ElnDocumentId"/>
<xsl:variable name="elnDocumentIDs" select="./Counterpart/Counterpart/CounterpartData/ElnDocumentId"/>
<xsl:call-template name="CheckInvolvedParties">
<xsl:with-param name="elnDocumentIDs" select="$elnDocumentIDs"/>
</xsl:call-template>
</xsl:for-each>
</SemanticErrors>
</xsl:template>
<!-- Check if each counterpart for a document ID contains the same set of involved-party reference IDs -->
<xsl:template name="CheckInvolvedParties">
<xsl:param name="elnDocumentIDs"/>
document IDs
<xsl:value-of select="$elnDocumentIDs"/>
<!-- For each document ID... -->
<xsl:for-each select="current()[ElnDocumentId=$elnDocumentIDs]">
<xsl:variable name="setOfAllCounterpartPartyIds" select="set:distinct(//InvolvedParty/PartyId)" xmlns:set="http://exslt.org/sets"/>
<xsl:for-each select="Counterpart">
<!-- For each document counterpart, make sure it contains just $setOfAllCounterpartPartyIds... -->
<xsl:call-template name="ValidateCounterpartsPartyIds">
<xsl:with-param name="setOfAllCounterpartPartyIds" select="$setOfAllCounterpartPartyIds"/>
</xsl:call-template>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<!-- -->
<xsl:template name="ValidateCounterpartsPartyIds">
<xsl:param name="setOfAllCounterpartPartyIds"/>
<!-- Check if there are any counterparts to check. -->
<xsl:if test="./*[text()]">
Counterpart ID [<xsl:value-of select="Counterpart/CounterpartData/ElnCounterpartId"/>]
setOfAllCounterpartPartyIds = [<xsl:copy-of select="$setOfAllCounterpartPartyIds"/>]
<xsl:variable name="partyIdsForThisCounterpart" select="Counterpart/CounterpartData/InvolvedParty/PartyId"/>
partyIdsForThisCounterpart = [<xsl:copy-of select="Counterpart/CounterpartData/InvolvedParty/PartyId"/>]
<xsl:variable name="setDifference" select="set:difference($setOfAllCounterpartPartyIds, $partyIdsForThisCounterpart)" xmlns:set="http://exslt.org/sets"/>
Are [<xsl:copy-of select="$setOfAllCounterpartPartyIds"/>] and [<xsl:copy-of select="$partyIdsForThisCounterpart"/>] the same? [<xsl:value-of select="count($setDifference) = 0"/>]
<xsl:if test="count($setDifference) > 0" xmlns:set="http://exslt.org/sets">
Validation error:
Those elements that are in the first set but not the second:
<xsl:copy-of select="$setOfAllCounterpartPartyIds[count(. | $partyIdsForThisCounterpart) != count($partyIdsForThisCounterpart)]"/>
</xsl:if>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
而且,我正在使用这个样式表:
xlsxwriter
答案 0 :(得分:1)
我还没有彻底完成逻辑,但据我所知,您需要一组不同的PartyID 值,而您的代码正在寻找不同的PartyID 节点< / em>的。两个不同的节点可能具有相同的值。
我担心XSLT 1.0中的这种问题非常棘手。我希望看到Muenchian分组的内容:为您的PartyID值定义一个键,当您遇到特定的PartyID时,将其替换为具有该特定值的第一个PartyID;一旦你完成了这个,不同的节点将代表不同的值。