我需要帮助在以下xml中的节点ExtraInfo中的节点FirstName之后封闭一些兄弟节点:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BatchMember>
<Member>
<FirstName>MICHAEL </FirstName>
<Books>
<Fiction>1</Fiction>
<ChildrensBooks> </ChildrensBooks>
</Books>
<Stationery>
<Art> </Art>
<Writing> </Writing>
</Stationery>
<CardsGifts>1</CardsGifts>
<ROINI>1</ROINI>
<Signed>1</Signed>
<Date>2011-10-04</Date>
</Member>
<Member>
<FirstName>JOHN </FirstName>
<Books>
<Fiction>1</Fiction>
<ChildrensBooks> </ChildrensBooks>
</Books>
<Stationery>
<Art>1</Art>
<Writing> </Writing>
</Stationery>
<CardsGifts>1</CardsGifts>
<ROINI> </ROINI>
<Signed>1</Signed>
<Date>2011-10-04</Date>
</Member>
</BatchMember>
我使用了以下xsl文件:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ex="http://exslt.org/dates-and-times" extension-element-prefixes="ex">
<xsl:strip-space elements="FirstName Surname Add1 Add2 City Email"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="BatchMember" >
<xsl:variable name="newline">
<xsl:text>
</xsl:text>
</xsl:variable>
<Batch>
<xsl:element name="Version" >1.0</xsl:element>
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</Batch>
</xsl:template>
<xsl:strip-space elements="*"/>
<xsl:key name="kFollowing" match="FirstName" use="generate-id(preceding-sibling::*[not(self::b)][1])"/>
<xsl:template match="FirstName[not(preceding-sibling::*[1][self::FirstName])]">
<ExtraInfo>
<xsl:copy-of select="key('kFollowing', generate-id(preceding-sibling::*[1]))"/>
</ExtraInfo>
</xsl:template>
<xsl:template match="FirstName"/>
<xsl:param name="true-text" select="'True'"/>
<xsl:param name="false-text" select="'False'"/>
<xsl:template match="FirstName">
</xsl:template>
<xsl:template match="Books">
<Category>
<Name>Books</Name>
<xsl:choose>
<xsl:when test="Fiction = 1">
<Fiction>
<xsl:value-of select="$true-text"/>
</Fiction>
</xsl:when>
<xsl:otherwise>
<Fiction>
<xsl:value-of select="$false-text"/>
</Fiction>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="ChildrensBooks = 1">
<ChildrensBooks>
<xsl:value-of select="$true-text"/>
</ChildrensBooks>
</xsl:when>
<xsl:otherwise>
<ChildrensBooks>
<xsl:value-of select="$false-text"/>
</ChildrensBooks>
</xsl:otherwise>
</xsl:choose>
</Category>
</xsl:template>
<xsl:template match="Stationery">
<Category>
<Name>Stationery</Name>
<xsl:choose>
<xsl:when test="Art = 1">
<Art>
<xsl:value-of select="$true-text"/>
</Art>
</xsl:when>
<xsl:otherwise>
<Art>
<xsl:value-of select="$false-text"/>
</Art>
</xsl:otherwise>
</xsl:choose>
<xsl:choose>
<xsl:when test="Writing = 1">
<Writing>
<xsl:value-of select="$true-text"/>
</Writing>
</xsl:when>
<xsl:otherwise>
<Writing>
<xsl:value-of select="$false-text"/>
</Writing>
</xsl:otherwise>
</xsl:choose>
</Category>
</xsl:template>
<xsl:template match="CardsGifts">
</xsl:template>
</xsl:stylesheet>
产生了以下结果:
<?xml version="1.0" ?>
- <Batch>
<Version>1.0</Version>
- <BatchMember>
- <Member>
- <ExtraInfo>
<FirstName>MICHAEL</FirstName>
<FirstName>JOHN</FirstName>
</ExtraInfo>
- <Category>
<Name>Books</Name>
<Fiction>True</Fiction>
<ChildrensBooks>False</ChildrensBooks>
</Category>
- <Category>
<Name>Stationery</Name>
<Art>False</Art>
<Writing>False</Writing>
</Category>
<ROINI>1</ROINI>
<Signed>1</Signed>
<Date>2011-10-04</Date>
</Member>
- <Member>
- <ExtraInfo>
<FirstName>MICHAEL</FirstName>
<FirstName>JOHN</FirstName>
</ExtraInfo>
- <Category>
<Name>Books</Name>
<Fiction>True</Fiction>
<ChildrensBooks>False</ChildrensBooks>
</Category>
- <Category>
<Name>Stationery</Name>
<Art>True</Art>
<Writing>False</Writing>
</Category>
<ROINI />
<Signed>1</Signed>
<Date>2011-10-04</Date>
</Member>
</BatchMember>
</Batch>
这是我要求的结果:
<?xml version="1.0"?>
<BatchMember>
<Version>1.0</Version>
<Member>
<FirstName>MICHAEL</FirstName>
<ExtraInfo>
<Category>
<Name>Books</Name>
<attribute>
<Name>Fiction</Name>
<Value>True</Value>
</attribute>
<attribute>
<Name>Children's</Name>
<Value>False</Value>
</attribute>
</Category>
<Category>
<Name>Stationery</Name>
<attribute>
<Name>Art</Name>
<Value>False</Value>
</attribute>
<attribute>
<Name>Writing</Name>
<Value>False</Value>
</attribute>
</Category>
</ExtraInfo>
</Member>
<Member>
<FirstName>JOHN</FirstName>
<ExtraInfo>
<Category>
<Name>Books</Name>
<attribute>
<Name>Fiction</Name>
<Value>True</Value>
</attribute>
<attribute>
<Name>Children's</Name>
<Value>False</Value>
</attribute>
</Category>
<Category>
<Name>Stationery</Name>
<attribute>
<Name>Art</Name>
<Value>True</Value>
</attribute>
<attribute>
<Name>Writing</Name>
<Value>False</Value>
</attribute>
</Category>
<ExtraInfo>
</Member>
</BatchMember>
我做错了什么?
问候
杰夫。
答案 0 :(得分:0)
我认为你的XSLT可能过于复杂。例如,您不一定需要 xsl:key 。
您可以做的是,当您匹配成员元素时,为 FirstName 元素添加一些定制编码以进行复制,然后继续匹配所有子元素
<xsl:template match="Member">
<xsl:copy>
<xsl:copy-of select="FirstName"/>
<ExtraInfo>
<xsl:apply-templates />
</ExtraInfo>
</xsl:copy>
</xsl:template>
但是,您需要一个空模板来再次匹配FirstName元素,以避免输出两次
<xsl:template match="FirstName" />
您还需要为图书和固定元素添加匹配模板,以便对这些元素进行特殊处理
<xsl:template match="Books|Stationery">
<Category>
<Name>
<xsl:value-of select="local-name()"/>
</Name>
<xsl:apply-templates select="*" mode="Attributes"/>
</Category>
</xsl:template>
您还需要一个模板来处理 Book 和固定元素的子项。我并不是100%确定你想要做什么,但是在预期的输出中,看起来你想将它们转换为属性元素。
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ex="http://exslt.org/dates-and-times" extension-element-prefixes="ex">
<xsl:strip-space elements="FirstName Surname Add1 Add2 City Email"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="BatchMember">
<Batch>
<Version>1.0</Version>
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</Batch>
</xsl:template>
<xsl:template match="Member">
<xsl:copy>
<xsl:copy-of select="FirstName"/>
<ExtraInfo>
<xsl:apply-templates />
</ExtraInfo>
</xsl:copy>
</xsl:template>
<xsl:template match="FirstName" />
<xsl:template match="Books|Stationery">
<Category>
<Name>
<xsl:value-of select="local-name()"/>
</Name>
<xsl:apply-templates select="*" mode="Attributes"/>
</Category>
</xsl:template>
<xsl:template match="*" mode="Attributes">
<attribute>
<Name>
<xsl:value-of select="local-name()"/>
</Name>
<Value>
<xsl:choose>
<xsl:when test=". = 1">True</xsl:when>
<xsl:otherwise>False</xsl:otherwise>
</xsl:choose>
</Value>
</attribute>
</xsl:template>
</xsl:stylesheet>
当应用于您的样本输入XML时,输出以下内容:
<Batch>
<Version>1.0</Version>
<BatchMember>
<Member>
<FirstName>MICHAEL </FirstName>
<ExtraInfo>
<Category>
<Name>Books</Name>
<attribute>
<Name>Fiction</Name>
<Value>True</Value>
</attribute>
<attribute>
<Name>ChildrensBooks</Name>
<Value>False</Value>
</attribute>
</Category>
<Category>
<Name>Stationery</Name>
<attribute>
<Name>Art</Name>
<Value>False</Value>
</attribute>
<attribute>
<Name>Writing</Name>
<Value>False</Value>
</attribute>
</Category>
<CardsGifts>1</CardsGifts>
<ROINI>1</ROINI>
<Signed>1</Signed>
<Date>2011-10-04</Date>
</ExtraInfo>
</Member>
<Member>
<FirstName>JOHN </FirstName>
<ExtraInfo>
<Category>
<Name>Books</Name>
<attribute>
<Name>Fiction</Name>
<Value>True</Value>
</attribute>
<attribute>
<Name>ChildrensBooks</Name>
<Value>False</Value>
</attribute>
</Category>
<Category>
<Name>Stationery</Name>
<attribute>
<Name>Art</Name>
<Value>True</Value>
</attribute>
<attribute>
<Name>Writing</Name>
<Value>False</Value>
</attribute>
</Category>
<CardsGifts>1</CardsGifts>
<ROINI/>
<Signed>1</Signed>
<Date>2011-10-04</Date>
</ExtraInfo>
</Member>
</BatchMember>
</Batch>
虽然它与您的预期输出不完全匹配(例如,它仍会输出 CardsGifts 元素),但我希望它可以为您提供一些工作。