我有以下XML示例:
<root>
<Customer>
<Name/>
<Address>
<AddressLine1/>
<AddressLine2/>
<AddressLine3/>
</Address>
</Customer>
<Provider>
<Region>
<County/>
</Region>
<HeadOffice>
<Address>
<Line1/>
<Line2/>
<Postcode>
<Sector/>
</Postcode>
</Address>
</HeadOffice>
</Provider>
</root>
我想为Address
元素和所有后代元素添加一个属性,以便我的输出看起来像这样:
<root>
<Customer>
<Name/>
<Address defer="true">
<AddressLine1 defer="true"/>
<AddressLine2 defer="true"/>
<AddressLine3 defer="true"/>
</Address>
</Customer>
<Provider>
<Region>
<County/>
</Region>
<HeadOffice>
<Address defer="true">
<Line1 defer="true"/>
<Line2 defer="true"/>
<Postcode defer="true">
<Sector defer="true"/>
</Postcode>
</Address>
</HeadOffice>
</Provider>
</root>
Address
元素可能有不同的父元素和不同的后代,但我总是希望将属性添加到它及其所有后代。
我有这个XSLT来完成这项工作:
<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:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Address|Address//*">
<xsl:element name="{local-name()}">
<xsl:attribute name="defer">true</xsl:attribute>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
但是<xsl:template match="Address|Address//*">
感觉很笨拙。
是否有一种更好/更优雅的方式来匹配元素及其所有后代,或者这是最好的方法吗?
答案 0 :(得分:2)
您的模式match="Address|Address//*"
是表达任何Address
元素和Address
元素的任何可能后代元素的匹配的正确方法。我不明白为什么它笨重或不优雅。您可以在我的视图中将<xsl:element name="{local-name()}">
更改为<xsl:copy>
,以便更优雅地复制匹配的元素,但当然优雅是个人判断。
答案 1 :(得分:1)
有关XSLT性能的规则之一是避免在XPath中使用“//”。 因此,如果性能是一个问题,您可以使用以下XSL:
<esc>:w data/temp.txt
另请注意,第二个模板中的<?xml version="1.0" encoding="UTF-8" ?>
<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:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[ancestor-or-self::Address]">
<xsl:element name="{local-name()}">
<xsl:attribute name="defer">true</xsl:attribute>
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
具有apply-templates
属性。
如果省略它,您将丢失其他属性(如果有)。