【问题标题】:XSLT Transform with original nested level具有原始嵌套级别的 XSLT 转换
【发布时间】:2014-11-14 04:52:05
【问题描述】:

我已对问题进行了编辑以使其清楚。 我想获取所有包含节节点和标题节点的节节点,保持嵌套级别。下面是我想要的输出结果:

<?xml version="1.0" encoding="UTF-8"?>
<results>
    <section id="intro" difficulty="easy">
        <title>Introduction</title>
        <section>
            <title>Web Data and the Two Cultures</title>
        </section>
    </section>
    <section id="syntax" difficulty="medium">
        <title>A Syntax For Data</title>
        <section>
            <title>Base Types</title>
        </section>
        <section>
            <title>Representing Relational Databases</title>
        </section>
        <section>
            <title>Representing Object Databases</title>
        </section>
    </section>
</results>

而xml内容是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="book.xsl"?>
<book>
    <title>Data on the Web</title>
    <author>Serge Abiteboul</author>
    <author>Peter Buneman</author>
    <author>Dan Suciu</author>
    <section id="intro" difficulty="easy">
        <title>Introduction</title>
        <p>Text ... </p>
        <section>
            <title>Web Data and the Two Cultures</title>
            <p>Text ... </p>
            <figure height="400" width="400">
                <title>Traditional client/server architecture</title>
                <image source="csarch.gif"/>
            </figure>
            <p>Text ... </p>
        </section>
    </section>
    <section id="syntax" difficulty="medium">
        <title>A Syntax For Data</title>
        <p>Text ... </p>
        <figure height="200" width="500">
            <title>Graph representations of structures</title>
            <image source="graphs.gif"/>
        </figure>
        <p>Text ... </p>
        <section>
            <title>Base Types</title>
            <p>Text ... </p>
        </section>
        <section>
            <title>Representing Relational Databases</title>
            <p>Text ... </p>
            <figure height="250" width="400">
                <title>Examples of Relations</title>
                <image source="relations.gif"/>
            </figure>
        </section>
        <section>
            <title>Representing Object Databases</title>
            <p>Text ... </p>
        </section>
    </section>
</book>

这是我的解决方案,这是错误的:

<?xml version="1.0" encoding="UTF-8"?>
<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="/book">
    <xsl:apply-templates select="section"/>
</xsl:template>
<xsl:template match="section">
    <xsl:element name="section">
        <xsl:for-each select="@*">
            <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
        </xsl:for-each>
    </xsl:element>
    <xsl:apply-templates select="title"/>
    <xsl:apply-templates select="section"/>
</xsl:template>
<xsl:template match="title">
    <xsl:element name="title">
        <xsl:for-each select="@*">
            <xsl:attribute name="{name()}"><xsl:value-of select="."/></xsl:attribute>
        </xsl:for-each>
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>
</xsl:stylesheet>

我正在考虑使用递归,但我没有找到如何在 XSLT 中做到这一点。 应该有其他方法。 提前致谢!

【问题讨论】:

  • You are using "pull" rather than "push" kind of programming in your XSLT 尝试使用更多apply-templates 而不是for-each
  • 您的 XSLT 代码完全没有意义。您是否从某个地方复制它只是为了表明您已经尝试过某些东西?您只需要identity transform template 和另一个将results 重命名为book 的模板。
  • 我确实写了这个。我从昨天开始一直在努力,我还在尝试。我上面的 XSLT 代码是为了打印 html 文档中的元素。但现在我知道我应该将方法属性设置为xsl:输出元素为“xml”。所以不会有像<这样的符号不再。但我仍然找不到保持缩进格式和嵌套层次结构的方法。 @michael.hor257k

标签: xml xslt


【解决方案1】:

如果您确实想要做的只是将book 元素重命名为results,您需要从XSLT identity template 开始

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

它会按原样复制源文档中的所有节点,这意味着您只需为要更改的节点编写模板。在这种情况下,您正在更改 book 元素,因此您将拥有一个特定的模板,如下所示:

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

此外,如果您想删除除 sectiontitle(和 book)之外的元素,一种方法是使用模板来匹配“其他”元素,然后忽略它们

<xsl:template match="*[not(self::book) and not(self::section) and not(self::title)]" />

就是这样!试试这个 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />

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

  <xsl:template match="*[not(self::book) and not(self::section) and not(self::title)]" />

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

但请记住,如果您使用&lt;?xml-stylesheet 在客户端进行转换,浏览器可能只显示文本,而不是 XML,因为它确实希望输出是 HTML。您可以通过查看(页面)源来查看实际结果。

【讨论】:

  • 抱歉,我认为我的描述造成了一些混乱。我只想要每个sectionsectiontitle。输出结果应该使每个section 具有正确的嵌套层次结构。
  • 您输入的 XML 仅包含 sectiontitle 元素,因此如果您展示一个包含其他元素的更具体的示例可能会有所帮助。谢谢!
  • 给定的输出和原始xml示例不仅在根节点不同。上面的输出包含&lt;!-- other nested section&gt;title node-set --&gt;,而原始xml示例包含&lt;!-- other elements --&gt;。较少关注的节点已被过滤.
  • 您是说您也想转换 cmets 中的文本吗?还是那里有实际的元素?请记住,我们只能回答摆在我们面前的问题,因此需要查看有代表性的样本才能给出准确的答案。谢谢
  • 不,我已经编辑了上面的示例。并添加了我再次编写的代码。我只想从 book.xml 中提取节和标题节点,保留层次结构。谢谢您的麻烦。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-31
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 2016-07-01
  • 2012-02-21
相关资源
最近更新 更多