gpt4 book ai didi

xml - xslt如何选择当前节点或先前的同级,但不能同时选择两者

转载 作者:行者123 更新时间:2023-12-03 17:03:13 31 4
gpt4 key购买 nike

所以我有看起来像这样的xml

<Data>
<History>
<z r="1" c1="BILL" c2="123" c3="02/20/2006" c4="100.00" c5=".00" c6=".00" c7="100.00" c8=".00" c9=".00" c10=".00" lcdesc="BILL"/>
<z r="2" c1="PAYCODE" c2="456" c3="03/16/2006" c4="-100.00" c5=".00" c6=".00" c7="-100.00" c8=".00" c9=".00" c10=".00" lcdesc="PAYMENT"/>
<z r="3" c1="Total" c2="123" c3="02/20/2006" c4=".00" c5=".00" c6=".00" c7=".00" c8=".00" c9=".00" c10=".00" lcdesc="Total"/>
<z r="4" lcdesc=""/>
<z r="5" c1="BILL" c2="124" c3="03/27/2006" c4="13000.00" c5="400.00" c6=".00" c7="13400.00" c8=".00" c9=".00" c10=".00" lcdesc="BILL"/>
<z r="6" c1="PAYCODE" c2="457" c3="04/13/2006" c4="-13000.00" c5="-400.00" c6=".00" c7="-13400.00" c8=".00" c9=".00" c10=".00" lcdesc="PAYMENT"/>
<z r="7" c1="Total" c2="124" c3="03/27/2006" c4=".00" c5=".00" c6=".00" c7=".00" c8=".00" c9=".00" c10=".00" lcdesc="Total"/>
<z r="8" lcdesc=""/>
<z r="9" c1="BILL" c2="125" c3="04/28/2006" c4="1000.00" c5=".00" c6=".00" c7="1000.00" c8=".00" c9=".00" c10=".00" lcdesc="BILL"/>
<z r="10" c1="PAYCODE" c2="458" c3="05/10/2006" c4="-1000.00" c5=".00" c6=".00" c7="-1000.00" c8=".00" c9=".00" c10=".00" lcdesc="PAYMENT"/>
<z r="11" c1="Total" c2="125" c3="04/28/2006" c4=".00" c5=".00" c6=".00" c7=".00" c8=".00" c9=".00" c10=".00" lcdesc="Total"/>
<z r="12" lcdesc=""/>
</History>
</Data>


我想将c1 =“ BILL” z节点中的某些信息放在后续行中。我想获取发票编号(c2)和发票日期(c3)。所以我想在模板中声明一个变量,然后选择当前节点(如果c1 ='BILL')或前一个同级节点(其中c1 ='BILL')。虽然它适用于第一个节点及其后续行,但在第二条帐单行上却放置了先前的帐单行信息。所以有些事情是不对的。你能帮我吗?

这是我无法使用的xslt:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="*|/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
<xsl:output indent="no"/>
<xsl:template match="/">
<History>
<xsl:apply-templates select="//History/z"/>
</History>
</xsl:template>


<xsl:template match="/PageData/History/z">
<xsl:variable name="invnode" select="current()[@c1 = 'BILL'] | preceding-sibling::z[@c1 = 'BILL'][1]" />
<z>
<xsl:for-each select="@*">
<!--get the attribute name-->
<xsl:variable name="nodename">
<xsl:value-of select="name()"/>
</xsl:variable>
<xsl:attribute name="{$nodename}"><xsl:value-of select="."/></xsl:attribute>
</xsl:for-each>
<xsl:attribute name="invoice"><xsl:value-of select="$invnode/@c2" /></xsl:attribute>
<xsl:if test="string-length($invnode/@c3) >= 10">
<xsl:attribute name="invdate1"><xsl:value-of select="concat(substring($invnode/@c3, 7), substring($invnode/@c3, 1, 2), substring($invnode/@c3, 4, 2))" /></xsl:attribute>
<xsl:attribute name="invdate2"><xsl:value-of select="concat(substring($invnode/@c3, 7), '-', substring($invnode/@c3, 1, 2), '-', substring($invnode/@c3, 4, 2))" /></xsl:attribute>
</xsl:if>
</z>
</xsl:template>

</xsl:stylesheet>


我想要的输出如下:

<Data>
<History>
<z r="1" c1="BILL" c2="123" c3="02/20/2006" c4="100.00" c5=".00" c6=".00" c7="100.00" c8=".00" c9=".00" c10=".00" lcdesc="BILL" invoice="123" invdate1="20060220" invdate2="2006-02-20" />
<z r="2" c1="PAYCODE" c2="456" c3="03/16/2006" c4="-100.00" c5=".00" c6=".00" c7="-100.00" c8=".00" c9=".00" c10=".00" lcdesc="PAYMENT" invoice="123" invdate1="20060220" invdate2="2006-02-20" />
<z r="3" c1="Total" c2="123" c3="02/20/2006" c4=".00" c5=".00" c6=".00" c7=".00" c8=".00" c9=".00" c10=".00" lcdesc="Total" invoice="123" invdate1="20060220" invdate2="2006-02-20" />
<z r="4" lcdesc="" invoice="123" invdate1="20060220" invdate2="2006-02-20" />
<z r="5" c1="BILL" c2="124" c3="03/27/2006" c4="13000.00" c5="400.00" c6=".00" c7="13400.00" c8=".00" c9=".00" c10=".00" lcdesc="BILL" invoice="124" invdate1="20060327" invdate2="2006-03-27" />
<z r="6" c1="PAYCODE" c2="457" c3="04/13/2006" c4="-13000.00" c5="-400.00" c6=".00" c7="-13400.00" c8=".00" c9=".00" c10=".00" lcdesc="PAYMENT" invoice="124" invdate1="20060327" invdate2="2006-03-27" />
<z r="7" c1="Total" c2="124" c3="03/27/2006" c4=".00" c5=".00" c6=".00" c7=".00" c8=".00" c9=".00" c10=".00" lcdesc="Total" invoice="124" invdate1="20060327" invdate2="2006-03-27" />
<z r="8" lcdesc="" invoice="124" invdate1="20060327" invdate2="2006-03-27" />
<z r="9" c1="BILL" c2="125" c3="04/28/2006" c4="1000.00" c5=".00" c6=".00" c7="1000.00" c8=".00" c9=".00" c10=".00" lcdesc="BILL" invoice="125" invdate1="20060428" invdate2="2006-04-28" />
<z r="10" c1="PAYCODE" c2="458" c3="05/10/2006" c4="-1000.00" c5=".00" c6=".00" c7="-1000.00" c8=".00" c9=".00" c10=".00" lcdesc="PAYMENT" invoice="125" invdate1="20060428" invdate2="2006-04-28" />
<z r="11" c1="Total" c2="125" c3="04/28/2006" c4=".00" c5=".00" c6=".00" c7=".00" c8=".00" c9=".00" c10=".00" lcdesc="Total" invoice="125" invdate1="20060428" invdate2="2006-04-28" />
<z r="12" lcdesc="" invoice="125" invdate1="20060428" invdate2="2006-04-28" />
</History>
</Data>

最佳答案

这样尝试吗?

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:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="z">
<xsl:variable name="invnode" select="current()[@c1='BILL'] | preceding-sibling::z[@c1 = 'BILL'][1][not(current()/@c1='BILL')]" />
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="invoice">
<xsl:value-of select="$invnode/@c2" />
</xsl:attribute>
<xsl:attribute name="invdate1">
<xsl:value-of select="concat(substring($invnode/@c3, 7), substring($invnode/@c3, 1, 2), substring($invnode/@c3, 4, 2))" />
</xsl:attribute>
<xsl:attribute name="invdate2">
<xsl:value-of select="concat(substring($invnode/@c3, 7), '-', substring($invnode/@c3, 1, 2), '-', substring($invnode/@c3, 4, 2))" />
</xsl:attribute>
</xsl:copy>
</xsl:template>

</xsl:stylesheet>




说明:

该表达式:

current()[@c1='BILL']


如果当前节点是发票,则选择当前节点;否则返回一个空节点集。

该表达式:

preceding-sibling::z[@c1 = 'BILL'][1][not(current()/@c1='BILL')]"


如果当前节点不是发票,则返回最接近的前一个发票。否则返回一个空节点集。

因此,在这两个表达式的并集中,子集之一将始终为空:


如果当前节点是发票,则左侧返回当前节点,而右侧为空。
如果当前节点不是发票,则左侧为空,而右侧返回最接近的前一兄弟,即发票。


因此,联合将永远只包含一个节点,并且顺序无关紧要。

关于xml - xslt如何选择当前节点或先前的同级,但不能同时选择两者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32723479/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com