在 XML 中添加元素.(XSLT)



我在正确格式化 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>

最新更新