如何使用 XSLT 转换一段简单的 XML

发布于 2024-11-10 00:31:26 字数 588 浏览 0 评论 0原文

如何转换

<person>
   <personFirstName>FirstName</personFirstName>
   <personLastName>LastName</personLastName>
   <personAge>40</personAge>
</person>

为使用 XSLT,如下所示:

<person>
   <name>
      <first>FirstName</first>
      <last>LastName</last>
   </name>
   <age>40</age>
</person>

此外,如果输入 XML 是人员节点的集合,

<persons>
   <person>
       ...
   </person>
</persons>

How can you convert

<person>
   <personFirstName>FirstName</personFirstName>
   <personLastName>LastName</personLastName>
   <personAge>40</personAge>
</person>

to

<person>
   <name>
      <first>FirstName</first>
      <last>LastName</last>
   </name>
   <age>40</age>
</person>

using XSLT, moreover, if the input XML is a collection of person nodes, like so:

<persons>
   <person>
       ...
   </person>
</persons>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

扬花落满肩 2024-11-17 00:31:27

关键是身份转换并在需要时覆盖它。

示例 XML

<persons>
  <person>
    <personFirstName>FirstName</personFirstName>
    <personLastName>LastName</personLastName>
    <personAge>40</personAge>
  </person>
  <person>
    <personFirstName>FirstName2</personFirstName>
    <personLastName>LastName2</personLastName>
    <personAge>100</personAge>
  </person>
</persons>

示例 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!--Identity Transform-->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="person">
    <person>
      <name>
        <first><xsl:apply-templates select="personFirstName"/></first>
        <last><xsl:apply-templates select="personLastName"/></last>
      </name>
      <age><xsl:apply-templates select="personAge"/></age>
    </person>
  </xsl:template>

  <xsl:template match="personFirstName|personLastName|personAge">
    <xsl:apply-templates/>
  </xsl:template>

</xsl:stylesheet>

输出

<persons>
   <person>
      <name>
         <first>FirstName</first>
         <last>LastName</last>
      </name>
      <age>40</age>
   </person>
   <person>
      <name>
         <first>FirstName2</first>
         <last>LastName2</last>
      </name>
      <age>100</age>
   </person>
</persons>

The key is the identity transform and overriding it when needed.

Sample XML

<persons>
  <person>
    <personFirstName>FirstName</personFirstName>
    <personLastName>LastName</personLastName>
    <personAge>40</personAge>
  </person>
  <person>
    <personFirstName>FirstName2</personFirstName>
    <personLastName>LastName2</personLastName>
    <personAge>100</personAge>
  </person>
</persons>

Sample XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!--Identity Transform-->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="person">
    <person>
      <name>
        <first><xsl:apply-templates select="personFirstName"/></first>
        <last><xsl:apply-templates select="personLastName"/></last>
      </name>
      <age><xsl:apply-templates select="personAge"/></age>
    </person>
  </xsl:template>

  <xsl:template match="personFirstName|personLastName|personAge">
    <xsl:apply-templates/>
  </xsl:template>

</xsl:stylesheet>

OUTPUT

<persons>
   <person>
      <name>
         <first>FirstName</first>
         <last>LastName</last>
      </name>
      <age>40</age>
   </person>
   <person>
      <name>
         <first>FirstName2</first>
         <last>LastName2</last>
      </name>
      <age>100</age>
   </person>
</persons>
叫嚣ゝ 2024-11-17 00:31:27

“推送式”解决方案

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="personFirstName">
  <name>
   <xsl:apply-templates mode="renameWrapped"
        select=".|../personLastName"/>
  </name>
 </xsl:template>

 <xsl:template match="personFirstName" mode="renameWrapped">
  <first><xsl:apply-templates/></first>
 </xsl:template>

 <xsl:template match="personLastName" mode="renameWrapped">
  <last><xsl:apply-templates/></last>
 </xsl:template>

 <xsl:template match="personAge">
  <age><xsl:apply-templates/></age>
 </xsl:template>
 <xsl:template match="personLastName"/>
</xsl:stylesheet>

应用于此 XML 文档时

<persons>
    <person>
        <personFirstName>FirstName</personFirstName>
        <personLastName>LastName</personLastName>
        <personAge>40</personAge>
    </person>
    <person>
        <personFirstName>FirstName2</personFirstName>
        <personLastName>LastName2</personLastName>
        <personAge>100</personAge>
    </person>
</persons>

生成所需的正确结果

<persons>
   <person>
      <name>
         <first>FirstName</first>
         <last>LastName</last>
      </name>
      <age>40</age>
   </person>
   <person>
      <name>
         <first>FirstName2</first>
         <last>LastName2</last>
      </name>
      <age>100</age>
   </person>
</persons>

说明:

  1. < strong>使用和覆盖标识规则/模板来包装和重命名元素。

  2. 要包装的元素在模式下重命名 renameWrapped

  3. personAge 元素在非修改模板中重命名,该模板覆盖名为 personAge 的元素的身份规则。

A "push-style" solution:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="personFirstName">
  <name>
   <xsl:apply-templates mode="renameWrapped"
        select=".|../personLastName"/>
  </name>
 </xsl:template>

 <xsl:template match="personFirstName" mode="renameWrapped">
  <first><xsl:apply-templates/></first>
 </xsl:template>

 <xsl:template match="personLastName" mode="renameWrapped">
  <last><xsl:apply-templates/></last>
 </xsl:template>

 <xsl:template match="personAge">
  <age><xsl:apply-templates/></age>
 </xsl:template>
 <xsl:template match="personLastName"/>
</xsl:stylesheet>

when applied on this XML document:

<persons>
    <person>
        <personFirstName>FirstName</personFirstName>
        <personLastName>LastName</personLastName>
        <personAge>40</personAge>
    </person>
    <person>
        <personFirstName>FirstName2</personFirstName>
        <personLastName>LastName2</personLastName>
        <personAge>100</personAge>
    </person>
</persons>

the wanted, correct result is produced:

<persons>
   <person>
      <name>
         <first>FirstName</first>
         <last>LastName</last>
      </name>
      <age>40</age>
   </person>
   <person>
      <name>
         <first>FirstName2</first>
         <last>LastName2</last>
      </name>
      <age>100</age>
   </person>
</persons>

Explanation:

  1. Using and overriding the identity rule/template for wrapping and renaming of elements.

  2. The elements to be wrapped are renamed in mode renameWrapped.

  3. The personAge element is renamed in a non-moded template that overrides the identity rule for elements named personAge.

长发绾君心 2024-11-17 00:31:26

这应该很容易。您可以尝试:

  • 匹配person,然后打开name,应用模板,关闭name,打开age,获取值来自personAge,关闭age
  • 匹配personFirstName,打开first,获取值,关闭first
  • personFirstNamepersonLastName 相同,

我认为 3 个不带循环的模板就足够了。试试吧!

It should be very easy. You can try to:

  • match person then open name, apply templates, close name, open age, get value from personAge, close age
  • match personFirstName, open first, get value, close first
  • same as personFirstName for personLastName

I think 3 templates wihtout loops should be enough. Try it!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文