我希望有人可以提供帮助,我无法弄清楚这一点,也许它无法完成。
我有以下XML,需要根据Document元素的条件更新RedressNumber和KnownTravelerNumber。我正在使用以下XSLT,但它无法正常工作。
如果DocTypeCode条件不为true,则应按原样复制属性。 如果condition为true,则应将属性值替换为DocID值。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="identity.xsl" />
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" encoding="UTF-8" />
<xsl:template match="ProfileRead">
<xsl:apply-imports />
</xsl:template>
<xsl:template match="ProfileRead/Profile/Traveler/Customer">
<xsl:copy>
<xsl:for-each select="Document">
<xsl:if test="@DocTypeCode = 'KTID'">
<xsl:attribute name="KnownTravelerNumber">
<xsl:value-of select="@DocID"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="@DocTypeCode = 'RDNR'">
<xsl:attribute name="RedressNumber">
<xsl:value-of select="@DocID"/>
</xsl:attribute>
</xsl:if>
</xsl:for-each>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ProfileRead/Profile/Traveler/Customer/@KnownTravelerNumber" />
<xsl:template match="ProfileRead/Profile/Traveler/Customer/@RedressNumber" />
<!-- remove element -->
<xsl:template match="ProfileRead/Profile/Traveler/Customer/Document[@DocTypeCode='KTID']" />
<xsl:template match="ProfileRead/Profile/Traveler/Customer/Document[@DocTypeCode='RDNR']" />
</xsl:stylesheet>
<ProfileRead>
<Profile>
<Traveler>
<Customer GenderCode="M" RedressNumber="321" KnownTravelerNumber="123">
<PersonName LanguageIDCode="EN-US">
<GivenName>John</GivenName>
<MiddleName>Long</MiddleName>
<SurName>Smith</SurName>
<NameSuffix>Junior</NameSuffix>
</PersonName>
<Document DocID="666" DocTypeCode="RDNR" />
<Document DocID="111" DocTypeCode="KAMAL" />
<Document DocID="222" DocTypeCode="FRANK" />
</Customer>
</Traveler>
</Profile>
</ProfileRead>
答案 0 :(得分:0)
你没有准确地显示你想要的结果,但是我正在按照“按原样复制”的短语...我认为你所要做的就是在处理你的属性之前复制你的属性。在XSLT中,您可以多次向输出元素添加一个属性节点,最后一个获胜...添加的早期文件只是被覆盖。
因此,在下面的文本中,我所做的只是先复制属性,然后处理它们,然后我取出了删除属性的模板匹配。
t:\ftemp>type profile.xml
<ProfileRead>
<Profile>
<Traveler>
<Customer GenderCode="M" RedressNumber="321" KnownTravelerNumber="123">
<PersonName LanguageIDCode="EN-US">
<GivenName>John</GivenName>
<MiddleName>Long</MiddleName>
<SurName>Smith</SurName>
<NameSuffix>Junior</NameSuffix>
</PersonName>
<Document DocID="666" DocTypeCode="RDNR" />
<Document DocID="111" DocTypeCode="KAMAL" />
<Document DocID="222" DocTypeCode="FRANK" />
</Customer>
</Traveler>
</Profile>
</ProfileRead>
t:\ftemp>call xslt2 profile.xml profile.xsl
<ProfileRead>
<Profile>
<Traveler>
<Customer GenderCode="M" RedressNumber="666" KnownTravelerNumber="123">
<PersonName LanguageIDCode="EN-US">
<GivenName>John</GivenName>
<MiddleName>Long</MiddleName>
<SurName>Smith</SurName>
<NameSuffix>Junior</NameSuffix>
</PersonName>
<Document DocID="111" DocTypeCode="KAMAL"/>
<Document DocID="222" DocTypeCode="FRANK"/>
</Customer>
</Traveler>
</Profile>
</ProfileRead>
t:\ftemp>type profile.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="identity.xsl" />
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" encoding="UTF-8" />
<xsl:template match="ProfileRead">
<xsl:apply-imports />
</xsl:template>
<xsl:template match="ProfileRead/Profile/Traveler/Customer">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:for-each select="Document">
<xsl:if test="@DocTypeCode = 'KTID'">
<xsl:attribute name="KnownTravelerNumber">
<xsl:value-of select="@DocID"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="@DocTypeCode = 'RDNR'">
<xsl:attribute name="RedressNumber">
<xsl:value-of select="@DocID"/>
</xsl:attribute>
</xsl:if>
</xsl:for-each>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<!-- remove element -->
<xsl:template match="ProfileRead/Profile/Traveler/Customer/Document[@DocTypeCode='KTID']" />
<xsl:template match="ProfileRead/Profile/Traveler/Customer/Document[@DocTypeCode='RDNR']" />
</xsl:stylesheet>
t:\ftemp>rem Done!