我在正确格式化 XML 时遇到问题。我正在从 mySQL 数据库中提取数据,它返回数据。
<Customers>
<Customer Telephone="#" Country="#" Postcode="#" County="" Town="#" Address2="#" Address1="#" Surname="#" Forename="#" Suffix="#" Middlename="#" Title="#" Id="#"/>
</Customers>
我需要这些属性作为元素,使用下面的文件XLST,快速搜索相当容易。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<Company>
<xsl:apply-templates/>
</Company>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="{name()}"><xsl:value-of select="."/></xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="{name()}"><xsl:value-of select="."/></xsl:element>
</xsl:template>
</xsl:stylesheet>
我最终得到了这样的数据。
<Company>
<Customers>
<Customer><Id>#</Id><Title>#</Title><Middlename>#</Middlename><Suffix>#</Suffix><Forename>#</Forename><Surname>#</Surname><Address1>#</Address1><Address2>#</Address2><Town>#</Town><County>#</County><Postcode>#</Postcode><Country>#</Country><Telephone>#</Telephone>
</Customer>
</Customers>
</Company>
但是,我需要使用 XSLT 在周围(地址 1 和地址 2)周围添加一个"<地址>地址>"元素,但真的很纠结如何做到这一点。我尝试过的几乎所有方法都会导致错误。
提前感谢,
您是否想到在 XSLT 样式表中两次使用相同的模板?
在处理Customer
元素的位置干预标识模板。Adresses
插入一个新元素,并在其中将模板仅应用于名称包含"地址"的属性:
<Adresses>
<xsl:apply-templates select="@*[contains(name(),'Address')]"/>
</Adresses>
只有这样,模板才能应用于Customer
的其余内容:
<xsl:apply-templates select="@*[not(contains(name(),'Address'))]|node()"/>
XSLT 样式表
<?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" indent="yes"/>
<xsl:template match="/">
<Company>
<xsl:apply-templates/>
</Company>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Customer">
<xsl:copy>
<Adresses>
<xsl:apply-templates select="@*[contains(name(),'Address')]"/>
</Adresses>
<xsl:apply-templates select="@*[not(contains(name(),'Address'))]|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Customer/@*">
<xsl:element name="{name()}"><xsl:value-of select="."/></xsl:element>
</xsl:template>
</xsl:stylesheet>
XML 输出
<?xml version="1.0" encoding="UTF-8"?>
<Company>
<Customers>
<Customer>
<Adresses>
<Address2>#</Address2>
<Address1>#</Address1>
</Adresses>
<Telephone>#</Telephone>
<Country>#</Country>
<Postcode>#</Postcode>
<County/>
<Town>#</Town>
<Surname>#</Surname>
<Forename>#</Forename>
<Suffix>#</Suffix>
<Middlename>#</Middlename>
<Title>#</Title>
<Id>#</Id>
</Customer>
</Customers>
</Company>
请注意,属性的顺序在 XML 中并不重要。XML 分析器以它喜欢的任何顺序提供元素的属性。在您的情况下,这意味着输出中Customer
的子元素的顺序将是任意的。
在此处在线试用此解决方案。
使用
<xsl:template match="Customer/@Address1">
<Addresses>
<Address1>
<xsl:value-of select="."/>
</Address1>
<Address2>
<xsl:value-of select="../@Address2"/>
</Address2>
</Addresses>
</xsl:template>
<xsl:template match="Customer/@Address2"/>
首先,您现有的样式表具有冲突的模板:您有不少于3个模板匹配@*
。
我建议你更具体一点(而且更短
):XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/Customers">
<Company>
<xsl:apply-templates/>
</Company>
</xsl:template>
<xsl:template match="Customer">
<xsl:copy>
<xsl:apply-templates select="@*[not(starts-with(name(), 'Address'))]"/>
<Addresses>
<xsl:apply-templates select="@*[starts-with(name(), 'Address')]"/>
</Addresses>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:element name="{name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>