XML合并节点
我有以下xml:XML合并节点,xml,xslt,Xml,Xslt,我有以下xml: <Root> <Item> <CityCode>ALV</CityCode> <AirportCode>ALV</AirportCode> <CityName>ANDORRA LA VELLA</CityName> <AirportName>Andorra La Vel
<Root>
<Item>
<CityCode>ALV</CityCode>
<AirportCode>ALV</AirportCode>
<CityName>ANDORRA LA VELLA</CityName>
<AirportName>Andorra La Vella Hlpt</AirportName>
<StateCode></StateCode>
<CountryCode>AD</CountryCode>
<AirportTypeCode>8</AirportTypeCode>
<AirportTypeName>Heliport, not scheduled</AirportTypeName>
</Item>
</Root>
阿尔夫
阿尔夫
安道尔拉维拉酒店
安道尔拉维拉酒店
公元
8.
直升机场,没有预定
我需要一个xslt来实现这一点:
<Root>
<Item>
<CityCode>ALV</CityCode>
<CityName>ANDORRA LA VELLA</CityName>
<CityNameComplete> ANDORRA LA VELLA (ALV) - Andorra La Vella Hlpt </CityNameComplete>
<Item>
<Root>
阿尔夫
安道尔拉维拉酒店
安道尔拉维拉(ALV)-安道尔拉维拉Hlpt
我知道如何获取前两个节点,但不知道如何“插入”最后一个节点 > P>有多种方法将它嵌入到完整的XSLT中,但是我们可以说,您认为<代码> <代码>元素是原始XML文档中的“代码> <代码>元素的替换。 然后,关键是XSLT的
元素:
<xsl:template match="/Root/Item/AirportName">
<CityNameComplete><xsl:value-of select="../CityName"/> (<xsl:value-of select="../AirportCode"/>) - <xsl:value-of select="."/></CityNameComplete>
</xsl:template>
<xsl:template match="/Root/Item">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<CityNameComplete><xsl:text> </xsl:text><xsl:value-of select="CityName"/> (<xsl:value-of select="AirportCode"/>) - <xsl:value-of select="AirportName"/><xsl:text> </xsl:text></CityNameComplete>
</xsl:copy>
</xsl:template>
() -
这将产生一个
<CityNameComplete>ANDORRA LA VELLA (ALV) - Andorra La Vella Hlpt</CityNameComplete>
安道尔机场(ALV)-安道尔机场Hlpt
结果中的元素
更新:如果您确实想在完整的城市名称周围添加空格,请在样式表中添加
:
<xsl:template match="/Root/Item/AirportName">
<CityNameComplete><xsl:text> </xsl:text><xsl:value-of select="../CityName"/> (<xsl:value-of select="../AirportCode"/>) - <xsl:value-of select="."/><xsl:text> </xsl:text></CityNameComplete>
</xsl:template>
() -
结果:
<CityNameComplete> ANDORRA LA VELLA (ALV) - Andorra La Vella Hlpt </CityNameComplete>
安道尔机场(ALV)-安道尔机场Hlpt
更新2:包含IATA代码
更新3:插入节点的另一种解决方案是将其添加到
元素的模板中:
<xsl:template match="/Root/Item/AirportName">
<CityNameComplete><xsl:value-of select="../CityName"/> (<xsl:value-of select="../AirportCode"/>) - <xsl:value-of select="."/></CityNameComplete>
</xsl:template>
<xsl:template match="/Root/Item">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
<CityNameComplete><xsl:text> </xsl:text><xsl:value-of select="CityName"/> (<xsl:value-of select="AirportCode"/>) - <xsl:value-of select="AirportName"/><xsl:text> </xsl:text></CityNameComplete>
</xsl:copy>
</xsl:template>
() -
请注意,您必须删除不希望准确获得输出的节点-因为您没有要求删除这些节点,而且我也不想把答案弄得乱七八糟,所以我没有包含任何关于如何删除的代码。一种方法是基于标识模板,并有一个额外的模板来匹配项元素,然后使用concat功能输出CityNameComplete元素:
<xsl:template match="Item">
<Item>
<xsl:apply-templates select="@*|node()"/>
<CityNameComplete>
<xsl:value-of select="concat(CityName, ' (', AirportCode, ') ', AirportName)"/>
</CityNameComplete>
</Item>
</xsl:template>
您还需要一个模板来忽略所有不想输出的元素。在这种情况下,除了CityCode和CityName元素之外的所有元素
<xsl:template match="Item/*[not(self::CityCode|self::CityName)]"/>
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Item/*[not(self::CityCode|self::CityName)]"/>
<xsl:template match="Item">
<Item>
<xsl:apply-templates select="@*|node()"/>
<CityNameComplete>
<xsl:value-of select="concat(CityName, ' (', AirportCode, ') ', AirportName)"/>
</CityNameComplete>
</Item>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当应用于输入XML时,将输出以下内容
<Root>
<Item>
<CityCode>ALV</CityCode>
<CityName>ANDORRA LA VELLA</CityName>
<CityNameComplete>ANDORRA LA VELLA (ALV) Andorra La Vella Hlpt</CityNameComplete>
</Item>
</Root>
阿尔夫
安道尔拉维拉酒店
安道尔拉维拉(ALV)安道尔拉维拉Hlpt
这里有一个版本可以处理丢失的
和/或
:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<!--Identity template. Matches everything that isn't matched
by another template and copies it without modification.-->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Item">
<!--Copy the current element (Item) to the output.-->
<xsl:copy>
<!--Apply templates to attributes of Item and also the
CityCode and CityName elements. All other nodes of
Item will not be processed.-->
<xsl:apply-templates select="CityCode|CityName|@*"/>
<CityNameComplete>
<!--Output the value of CityName.-->
<xsl:value-of select="CityName"/>
<!--Apply the template for AirportCode. If it doesn't exist,
nothing will be output.-->
<xsl:apply-templates select="AirportCode"/>
<!--Apply the template for AirportName. If it doesn't exist,
nothing will be output.-->
<xsl:apply-templates select="AirportName"/>
</CityNameComplete>
</xsl:copy>
</xsl:template>
<xsl:template match="AirportCode">
<!--Output the value of AirportCode, surrounded by parenthesis and
preceded by a space.-->
<xsl:value-of select="concat(' (',.,')')"/>
</xsl:template>
<xsl:template match="AirportName">
<!--Output the value of AirportName, preceded by a "space dash space".-->
<xsl:value-of select="concat(' - ',.)"/>
</xsl:template>
</xsl:stylesheet>
我设法删除了不需要的节点,但我不确定如何保留根和项。我的输出是这样的:ALV ANDORR LA VELLA ANDORR LA VELLA(ALV)-ANDORR LA VELLA Hlpt@OanaAnton:请参阅XSLT标识模板的说明,例如:它基本上将源Xml文档的全部内容复制到输出,除了XSLT中与其他模板匹配的节点。@Mapper:谢谢您的帮助。这是我第一次使用XML、XSLT,一切都是新的。谢谢!关于如何工作的详细解释在哪里?事实上,这个答案对未来的访问者没有多大帮助。@O.R.Mapper-代码足够简单,我认为不需要详细解释。OP在接受答案之前没有任何问题,任何未来的访客也可以要求澄清。我添加了注释来解释代码的作用。如果你有一个评论中没有提到的具体问题,请让我知道。啊,好吧,通常情况下,互联网上的一个常量是,当未来的访问者真正提出问题时,原始答案作者不会再回答;-)最好在为时已晚之前立即提供解释。