如果符合某些条件,我需要在会计系统中向用户发出警告。
下面是我的XML片段,非常简洁,仅显示相关部分:
<DATA>
<ACCOUNTING>
<POSTINGS>
<POSTING KEY="815" ID="PR0">
...
<EXPENSE_TYPE_ID NAME="Expense Type ABC">123456</EXPENSE_TYPE_ID>
<AMOUNT>40000</AMOUNT>
...
</POSTING>
</POSTINGS>
<LINES>
<LINE KEY="1450" POSTING="PR0">
...
<BOOKKEEPING_TYPE>D</BOOKKEEPING_TYPE>
<ACCOUNT_ID NAME="Debit Account Name HHHH">112233</ACCOUNT_ID>
<AMOUNT>40000</AMOUNT>
<DESCRIPTION>Expense Type ABC</DESCRIPTION>
<SPECIALS_TYPE_A>1</SPECIALS_TYPE_A>
...
</LINE>
<LINE KEY="1451" POSTING="PR0">
...
<BOOKKEEPING_TYPE>C</BOOKKEEPING_TYPE>
<ACCOUNT_ID NAME="Credit Account Name TTTT">987654</ACCOUNT_ID>
<AMOUNT>-40000</AMOUNT>
<DESCRIPTION>Expense Type ABC</DESCRIPTION>
<SPECIALS_TYPE_A>1</SPECIALS_TYPE_A>
...
</LINE>
</LINES>
</ACCOUNTING>
</DATA>
必须根据以下标准显示消息:
以下是我当前的实现,在&#34; normal&#34;例:
<xsl:variable name="AmountWarningLower" select="20000" />
<xsl:for-each select="ACCCOUNTING/LINES/LINE[
DESCRIPTION = 'Expense Type ABC' or
DESCRIPTION = 'Expense Type DEF' or
...
]">
<xsl:if test="(SPECIALS_TYPE_A = '1') and
(AMOUNT > $AmountWarningLower) and
not(contains(ACCOUNT_ID/@NAME,'Tax Account'))
and not(BOOKKEEPING_TYPE='C')">
//Print message
//Print message
</xsl:if>
</xsl:for-each>
目前,我已经通过一长串OR来解决了要求#5,以匹配发布行的描述。
这并不理想,因为客户可以选择更改费用类型的描述,这将破坏我的解决方案。
但是因为应用程序在Line实体中不包含费用类型ID,所以我无法直接映射它们。
反之亦然,该应用程序在过帐实体中不包含特殊类型信息。
我看到&#34; Posting Record ID&#34;中的行之间存在关键匹配,即。 &#34; PR0&#34;
&#34; KEY&#34;两者之间没有直接联系。
我有什么方法可以加入&#34;两个XML实体,通过匹配&#34;发布记录ID&#34;,即。 &#34; PR0&#34;,然后更新我的解决方案以匹配来自过帐实体的费用类型ID,而不是来自Line实体的行描述?
理想情况如下:
<xsl:for-each select="ACCCOUNTING/LINES/LINE[
@EXPENSE_TYPE_ID = '123456' or
@EXPENSE_TYPE_ID = '789123' or
...
]">
希望这是有道理的,也是可能的。
提前感谢您帮助找到解决方案。
答案 0 :(得分:0)
我需要在XML实体之间进行交叉引用,作为不同的部分 信息列在不同的实体中。
密钥的作用:首先,您定义查找的实体和密钥值:
<xsl:key name="postings-by-id" match="POSTING" use="ID" />
现在,每次使用值为&#34; PRO&#34;时,它都将解决具有匹配ID值的POSTING节点 - 例如,您可以执行以下操作:
<xsl:for-each select="ACCCOUNTING/LINES/LINE">
<xsl:variable name="posting-code" select="key('postings-by-id', @POSTING)/@KEY" />
...
由于在定义变量之前无法使用变量,并且对键的重复引用会很麻烦,因此在您的情况下反转键操作的方向可能更方便。
考虑以下简化示例:
<强> XML 强>
<root>
<categories>
<category id="501" name="red"/>
<category id="502" name="green"/>
<category id="503" name="blue"/>
</categories>
<items>
<item id="1" category="red"/>
<item id="2" category="blue"/>
<item id="3" category="green"/>
<item id="4" category="blue"/>
<item id="5" category="red"/>
<item id="6" category="green"/>
<item id="7" category="blue"/>
<item id="8" category="red"/>
<item id="8" category="green"/>
<item id="9" category="blue"/>
</items>
</root>
在这里,我们希望只选择&#34;绿色&#34;中的项目。或者&#34;蓝色&#34;类别 - 但要使用类别id
值&#34; 502&#34;和&#34; 503&#34;。
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="item-by-category" match="item" use="@category" />
<xsl:template match="/root">
<xsl:copy>
<xsl:for-each select="key('item-by-category', categories/category[@id ='502' or @id ='503']/@name)">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<强>结果强>
<?xml version="1.0" encoding="UTF-8"?>
<root>
<item id="2" category="blue"/>
<item id="3" category="green"/>
<item id="4" category="blue"/>
<item id="6" category="green"/>
<item id="7" category="blue"/>
<item id="8" category="green"/>
<item id="9" category="blue"/>
</root>