首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XSLT样式表删除子元素,而不是重命名它们。

XSLT样式表删除子元素,而不是重命名它们。
EN

Stack Overflow用户
提问于 2015-03-30 21:04:31
回答 2查看 114关注 0票数 0

我有一些非常粗糙的XML,这些XML是从Fil怪人导出的。有一篇很棒的文章几乎回答了我的问题(XSLT question. How to pair field tags with data when original XML has them in separate sections?)。文章中的xslt样式表优雅地将丑陋的原始xml重命名为<meta>字段中的名称。

这很好,除非您在下面看到每一行都有多个元素,它们应该被命名为batchIDbatchPartnerIDbatchPartnerName。然而,只重命名了这三个元素的第一个子元素-其余的元素只是简单地删除。

我猜想样式表只是没有遍历元素(它最初使用的xml每个<COL>只有一个子元素。不幸的是,我还不太熟悉XSLT来解决这个问题.帮个小忙?谢谢。

原始XML

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult">
  <ERRORCODE>0</ERRORCODE>
  <PRODUCT BUILD="11-13-2014" NAME="FileMaker" VERSION="Pro 13.0v4"/>
  <DATABASE DATEFORMAT="M/d/yyyy" LAYOUT="" NAME="ArticleIndex.fmp12" RECORDS="3678" TIMEFORMAT="h:mm:ss a"/>
  <METADATA>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="id" TYPE="NUMBER"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="author" TYPE="TEXT"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="url" TYPE="TEXT"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="brand" TYPE="TEXT"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="publishDate" TYPE="TEXT"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="categoryAll" TYPE="TEXT"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="originalTitle" TYPE="TEXT"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="originalBody" TYPE="TEXT"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="standardTitle" TYPE="TEXT"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="standardSubtitle" TYPE="TEXT"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="standardPublishDate" TYPE="TEXT"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="standardBody" TYPE="TEXT"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="standardNotes" TYPE="TEXT"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="standardLastUpdated" TYPE="DATE"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="standardLastReviewed" TYPE="DATE"/>
    <FIELD EMPTYOK="NO" MAXREPEAT="1" NAME="batchID" TYPE="NUMBER"/>
    <FIELD EMPTYOK="NO" MAXREPEAT="1" NAME="batchPartnerID" TYPE="NUMBER"/>
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="batchPartnerName" TYPE="TEXT"/>
  </METADATA>
  <RESULTSET FOUND="12">
    <ROW MODID="24" RECORDID="2028">
      <COL>
        <DATA>11023</DATA>
      </COL>
      <COL>
        <DATA>Tom Myer</DATA>
      </COL>
      <COL>
        <DATA>http://www.sitepoint.com/really-good-introduction-xml/</DATA>
      </COL>
      <COL>
        <DATA>SitePoint</DATA>
      </COL>
      <COL>
        <DATA>August 2005</DATA>
      </COL>
      <COL>
        <DATA/>
      </COL>
      <COL>
        <DATA>A Really Good Introduction to XML</DATA>
      </COL>
      <COL>
        <DATA>A Really Good Introduction to XML —E. Berliet, Lyon, France

In this chapter, we’ll cover the basics of XML – essentially, most of the information you’ll need to know to get a handle on this exciting technology. After we’re done exploring some terminology and examples, we’ll jump right in and start working with XML documents. Then, we’ll spend some time starting the project we’ll develop through the course of this book: building an XML-powered content management system.

This excerpt is taken from No Nonsense XML Web Development with PHP, SitePoint’s new release, by Thomas Myer, which was designed to help you start using XML to build intelligent ‘Future-Proof’ PHP applications today.</DATA>
      </COL>
      <COL>
        <DATA>A Really, Really, Really Good Introduction to XML</DATA>
      </COL>
      <COL>
        <DATA>Starting out right</DATA>
      </COL>
      <COL>
        <DATA>8/24/2005</DATA>
      </COL>
      <COL>
        <DATA>A Really, Really, Really Good Introduction to XML —E. Berliet, Lyon, France

In this chapter, we’ll cover the basics of XML – essentially, most of the information you’ll need to know to get a handle on this exciting technology. After we’re done exploring some terminology and examples, we’ll jump right in and start working with XML documents. Then, we’ll spend some time starting the project we’ll develop through the course of this book: building an XML-powered content management system.

This excerpt is taken from No Nonsense XML Web Development with PHP, SitePoint’s new release, by Thomas Myer, which was designed to help you start using XML to build intelligent ‘Future-Proof’ PHP applications today.

The title contains over 350 pages of XML and PHP goodies. It walks you through the process of building a fully-functional XML-based content management system with PHP. And all the code used in the book is available to customers in a downloadalbe archive.

To find out more about “No Nonsense XML Web Development with PHP”, visit the book’s information page, or review the contents of the entire publication. As always, you can download this excerpt as a PDF if you prefer.
     </COL>
      <COL>
        <DATA/>
      </COL>
      <COL>
        <DATA/>
      </COL>
      <COL>
        <DATA/>
      </COL>
      <COL>
        <DATA>4127</DATA>
        <DATA>4130</DATA>
        <DATA>4136</DATA>
      </COL>
      <COL>
        <DATA>1101</DATA>
        <DATA>1107</DATA>
        <DATA>1140</DATA>
      </COL>
      <COL>
        <DATA>First Client Name</DATA>
        <DATA>Second Client Name</DATA>
        <DATA>Third Client Name</DATA>
      </COL>
    </ROW>
  </RESULTSET>
</FMPXMLRESULT>

XSLT样式表

代码语言:javascript
复制
<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fmp="http://www.filemaker.com/fmpxmlresult"
  exclude-result-prefixes="fmp"
>
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>

  <!-- the key indexes the METADATA fields by their position -->
  <xsl:key 
    name="kMetaData" 
    match="fmp:METADATA/fmp:FIELD" 
    use="count(preceding-sibling::fmp:FIELD) + 1" 
  />

  <!-- separate templates increase readability -->
  <xsl:template match="/fmp:FMPXMLRESULT">
    <content>
      <xsl:apply-templates select="fmp:RESULTSET/fmp:ROW" />
    </content>
  </xsl:template>

  <xsl:template match="fmp:ROW">
    <contentitem>
      <xsl:apply-templates select="fmp:COL" />
    </contentitem>
  </xsl:template>

  <xsl:template match="fmp:COL">
    <!-- column name lookup is high-speed because of the key -->
    <xsl:element name="{string(key('kMetaData', position())/@NAME)}">
      <xsl:value-of select="fmp:DATA" />
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

翻译的XML

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<content>
  <contentitem>
    <id>11023</id>
    <author>Tom Myer</author>
    <url>http://www.sitepoint.com/really-good-introduction-xml/</url>
    <brand>SitePoint</brand>
    <publishDate>August 2005</publishDate>
    <categoryAll/>
    <originalTitle>A Really Good Introduction to XML</originalTitle>
    <originalBody>A Really Good Introduction to XML —E. Berliet, Lyon, France

In this chapter, we’ll cover the basics of XML – essentially, most of the information you’ll need to know to get a handle on this exciting technology. After we’re done exploring some terminology and examples, we’ll jump right in and start working with XML documents. Then, we’ll spend some time starting the project we’ll develop through the course of this book: building an XML-powered content management system.

This excerpt is taken from No Nonsense XML Web Development with PHP, SitePoint’s new release, by Thomas Myer, which was designed to help you start using XML to build intelligent ‘Future-Proof’ PHP applications today.</originalBody>
    <standardTitle>A Really, Really, Really Good Introduction to XML</standardTitle>
    <standardSubtitle>Starting out right</standardSubtitle>
    <standardPublishDate>8/24/2005</standardPublishDate>
    <standardBody>A Really, Really, Really Good Introduction to XML —E. Berliet, Lyon, France

In this chapter, we’ll cover the basics of XML – essentially, most of the information you’ll need to know to get a handle on this exciting technology. After we’re done exploring some terminology and examples, we’ll jump right in and start working with XML documents. Then, we’ll spend some time starting the project we’ll develop through the course of this book: building an XML-powered content management system.

This excerpt is taken from No Nonsense XML Web Development with PHP, SitePoint’s new release, by Thomas Myer, which was designed to help you start using XML to build intelligent ‘Future-Proof’ PHP applications today.

The title contains over 350 pages of XML and PHP goodies. It walks you through the process of building a fully-functional XML-based content management system with PHP. And all the code used in the book is available to customers in a downloadalbe archive.

To find out more about “No Nonsense XML Web Development with PHP”, visit the book’s information page, or review the contents of the entire publication. As always, you can download this excerpt as a PDF if you prefer.</standardBody>
    <standardNotes/>
    <standardLastUpdated/>
    <standardLastReviewed/>
    <batchID>4127</batchID>
    <batchPartnerID>1101</batchPartnerID>
    <batchPartnerName>First Client Name</batchPartnerName>
  </contentitem>
</content>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-03-31 05:26:16

或者简单地说:

代码语言:javascript
复制
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fmp="http://www.filemaker.com/fmpxmlresult"
exclude-result-prefixes="fmp">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:key name="kMetaData" match="fmp:METADATA/fmp:FIELD" use="count(preceding-sibling::fmp:FIELD) + 1" />

<!-- separate templates are not required for something as simple as this -->
<xsl:template match="/">
    <content>
        <xsl:for-each select="fmp:FMPXMLRESULT/fmp:RESULTSET/fmp:ROW">
            <contentitem>
                <xsl:for-each select="fmp:COL">
                    <xsl:variable name="field-name" select="key('kMetaData', position())/@NAME" />
                    <xsl:for-each select="fmp:DATA">
                        <xsl:element name="{$field-name}">
                            <xsl:value-of select="." />
                        </xsl:element>
                    </xsl:for-each>
                </xsl:for-each>
            </contentitem>
        </xsl:for-each>
    </content>
</xsl:template>

</xsl:stylesheet>

请注意,这是假设您的字段名(并且将永远是)也是有效的XML元素名称。如果无法确定这一点,则在导出时切换到FMPDSORESULT语法。这将将您的字段名转换为有效的XML名称(例如,用下划线替换空格),但您还需要一个不同的XSLT样式表。

编辑:

例如,将以下FMPDSORESULT导出作为输入:

XML

代码语言:javascript
复制
<FMPDSORESULT xmlns="http://www.filemaker.com/fmpdsoresult">
<ERRORCODE>0</ERRORCODE>
<DATABASE>example.fmp12</DATABASE>
<LAYOUT/>
<ROW MODID="1" RECORDID="1">
<some_field>Alpha</some_field>
<another_field>
<DATA>101</DATA>
<DATA>102</DATA>
<DATA>103</DATA>
</another_field>
</ROW>
<ROW MODID="2" RECORDID="2">
<some_field>Bravo</some_field>
<another_field>
<DATA>21</DATA>
<DATA>22</DATA>
</another_field>
</ROW>
</FMPDSORESULT>

以下样式表:

XSLT1.0

代码语言:javascript
复制
<xsl:stylesheet version='1.0'       
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'
xmlns:fmp="http://www.filemaker.com/fmpdsoresult"
exclude-result-prefixes="fmp">
<xsl:output version="1.0" encoding="UTF-8" method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <root>
        <xsl:for-each select="fmp:FMPDSORESULT/fmp:ROW">
            <row> 
                <xsl:apply-templates/>
            </row>
        </xsl:for-each>
    </root>
</xsl:template>

<xsl:template match="fmp:ROW/*[not(fmp:DATA)]">
    <xsl:element name="{name(.)}">
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>

<xsl:template match="fmp:DATA">
    <xsl:element name="{name(..)}">
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

将返回:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <row>
    <some_field>Alpha</some_field>
    <another_field>101</another_field>
    <another_field>102</another_field>
    <another_field>103</another_field>
  </row>
  <row>
    <some_field>Bravo</some_field>
    <another_field>21</another_field>
    <another_field>22</another_field>
  </row>
</root>
票数 1
EN

Stack Overflow用户

发布于 2015-03-30 21:16:44

因此,听起来您需要三个具有三个batchID值的<DATA>值,而对于batchPartnerIDbatchPartnerName则是相同的。是那么回事吗?

如果是这样的话,您可以使用for-each来迭代<DATA>s:

代码语言:javascript
复制
<xsl:template match="fmp:COL">
  <xsl:variable name="elName"
                select="key('kMetaData', position())/@NAME" />
  <xsl:for-each select="fmp:DATA">
    <xsl:element name="{$elName}">
      <xsl:value-of select="." />
    </xsl:element>
  </xsl:for-each>
</xsl:template>

也可以使用参数化模板:

代码语言:javascript
复制
<xsl:template match="fmp:COL">
  <xsl:apply-templates select="fmp:DATA">
    <xsl:with-param name="elName" select="key('kMetaData', position())/@NAME" />
  </xsl:apply-templates>
</xsl:template>

<xsl:template match="fmp:DATA">
  <xsl:param name="elName" select="name()" />

  <xsl:element name="{$elName}">
    <xsl:value-of select="." />
  </xsl:element>
</xsl:template>
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29356257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档