如何使用子节点的 xslt 从 xml 获取以下兄弟节点 [英] How to get following sibling from xml using xslt from child node

查看:35
本文介绍了如何使用子节点的 xslt 从 xml 获取以下兄弟节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 XSL 和 XSLT 的新手,我一直在尝试获取我节点的以下兄弟节点,但在尝试了多种方法后,它仍然无法正常工作.我正在使用这个 glyph/image/following-siblings::image[1]/path 来引用以下兄弟.

这就是我的 XML 结构.

<?xml version="1.0" encoding="UTF-8"?><side id="Aa"><line id="Aa01"><glyph id="Aa01-001"><image id="Aa01-001-b" type="b"><path id="path-1" d=""/><x>7.6107272</x><y>21.662689</y><宽度>52.389273</宽度><高度>55.234216</高度></图像><image id="Aa01-001-f" type="f"><path id="path-2" d=""/><x>9.9999</x><y>25.437278</y><宽度>34.33299</宽度><height>73.835859</height></图像></字形><glyph id="Aa01-002"><image id="Aa01-002-b" type="b"><path id="path-3" d=""/><x>58.25</x><y>21.41996</y><宽度>22.113771</宽度><height>75.019102</height></图像><image id="Aa01-002-f" type="f"><path id="path-4" d=""/><x>63.205795</x><y>24.00143</y><宽度>22.582803</宽度><height>74.659189</height></图像></字形></行></侧面></平板电脑>

我的 XSLT 看起来像这样.

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE xsl:stylesheet PUBLIC "非官方 XSLT 1.0 DTD" "http://www.w3.org/1999/11/xslt10.dtd"><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"><xsl:output method="html" indent="yes"/><!-- 主模板--><xsl:template match="/"><div><xsl:apply-templates select="tablet"/>

</xsl:模板><!-- 平板电脑--><xsl:template match="tablet"><xsl:apply-templates select="side"/></xsl:模板><!-- 侧面--><xsl:template match="side"><h2><xsl:copy-of select="@id"/><xsl:value-of select="side-name"/><xsl:apply-templates select="line"/></xsl:模板><!-- 行--><xsl:template match="line"><xsl:variable name="curLine" select="line-num"/><h3><xsl:copy-of select="@id"/><xsl:text>行 </xsl:text><xsl:value-of select="line-num"/><xsl:call-template name="drawGlyphLine"/></xsl:模板><!-- 字形--><xsl:template name="drawGlyphLine"><p><xsl:text>字形:</xsl:text><xsl:value-of select="count(glyph/image[@type=$display-type])"/></p><div><xsl:attribute name="height"><xsl:value-of select="160"/></xsl:attribute><xsl:属性名称=宽度"><xsl:value-of select="svg-width[@type=$display-type]"/></xsl:attribute><xsl:apply-templates select="glyph/image[@type=$display-type]"/>

</xsl:模板><!-- 字形图像--><xsl:template match="字形/图像"><g><xsl:copy-of select="glyph/image/following-siblings::image[1]/path"><!--这里我想要路径的前一个兄弟节点--></xsl:copy-of><g><xsl:copy-of select="path"><!-- 这一行使输出成为路径的副本--></xsl:copy-of><g><xsl:copy-of select="glyph/image/preceding-sibling::image[1]/path"><!--这里我想要路径的下一个兄弟--></xsl:copy-of></svg></xsl:模板></xsl:stylesheet>

在输出中,我想要当前路径的以下兄弟.我没有添加完整的代码原因是没有让它不必要地长.基本上,完整代码会自动复制路径并呈现 SVG.现在我只想要下一个和上一个兄弟姐妹.

现在输出应该是这样的.

<!-- 上一个路径节点--><path id="path-1" d=""/><x>7.6107272</x><y>21.662689</y><宽度>52.389273</宽度><高度>55.234216</高度><!-- 下一个路径节点--></svg><!-- 上一个路径节点--><path id="path-2" d=""/><x>7.6107272</x><y>21.662689</y><宽度>52.389273</宽度><高度>55.234216</高度><!-- 下一个路径节点--></svg><!-- 上一个路径节点--><path id="path-3" d=""/><x>7.6107272</x><y>21.662689</y><宽度>52.389273</宽度><高度>55.234216</高度><!-- 下一个路径节点--></svg><!-- 上一个路径节点--><path id="path-4" d=""/><x>7.6107272</x><y>21.662689</y><宽度>52.389273</宽度><高度>55.234216</高度><!-- 下一个路径节点--></svg><!-- 上一个路径节点--><path id="path-5" d=""/><x>7.6107272</x><y>21.662689</y><宽度>52.389273</宽度><高度>55.234216</高度><!-- 下一个路径节点-->

解决方案

您的示例具有唯一的图像 ID.但是,如果要向前和向后遍历,则可以使用 preceding 轴.也就是说,如果它不会导致任何性能问题.

在您的 glyph/image 模板中,首先将 @id 存储在一个变量中

然后在前轴或后轴中遍历时使用它

previous::image[@id=$curr_id][1]/path以下::图像[@id=$curr_id][1]/路径

您的模板应如下所示:

<xsl:variable name="curr_id";选择=@id"/><g><xsl:copy-of select="preceding::image[@id=$curr_id][1]/path"><!--这里我想要路径的前一个兄弟节点--></xsl:copy-of><g><xsl:copy-of select="path"><!-- 这一行使输出成为路径的副本--></xsl:copy-of><g><xsl:copy-of select="following::image[@id=$curr_id][1]/path"><!--这里我想要路径的下一个兄弟--></xsl:copy-of></svg></xsl:模板>

我在以下链接中修改了您的示例(http://xsltransform.net/pPgCH6G).如果我的假设是正确的,那就应该这样做.

I am new in XSL and XSLT and I have been trying to get the following sibling of my node but after trying several methods it is still not working. I am using this glyph/image/following-siblings::image[1]/path to reference following sibling.

This is how my XML structured.

<?xml version="1.0" encoding="UTF-8"?>
<tablet id="A">
    <side id="Aa">
        <line id="Aa01">
            <glyph id="Aa01-001">
                <image id="Aa01-001-b" type="b">
                    <path id="path-1" d=""/>
                    <x>7.6107272</x>
                    <y>21.662689</y>
                    <width>52.389273</width>
                    <height>55.234216</height>
                </image>
                <image id="Aa01-001-f" type="f">
                    <path id="path-2" d=""/>
                    <x>9.9999</x>
                    <y>25.437278</y>
                    <width>34.33299</width>
                    <height>73.835859</height>
                </image>
            </glyph>
            <glyph id="Aa01-002">
                <image id="Aa01-002-b" type="b">
                    <path id="path-3" d=""/>
                    <x>58.25</x>
                    <y>21.41996</y>
                    <width>22.113771</width>
                    <height>75.019102</height>
                </image>
                <image id="Aa01-002-f" type="f">
                    <path id="path-4" d=""/>
                    <x>63.205795</x>
                    <y>24.00143</y>
                    <width>22.582803</width>
                    <height>74.659189</height>
                </image>
            </glyph>
    </line>
    </side>
</tablet>

And my XSLT looks like this.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE xsl:stylesheet PUBLIC "Unofficial XSLT 1.0 DTD" "http://www.w3.org/1999/11/xslt10.dtd">

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

 <!--  Main template  -->

 <xsl:template match="/">
  <div>
   <xsl:apply-templates select="tablet"/>
  </div>
 </xsl:template>

 <!-- Tablet -->

 <xsl:template match="tablet">
  <xsl:apply-templates select="side"/>
 </xsl:template> 

 <!-- Side -->

 <xsl:template match="side">
  <h2>
   <xsl:copy-of select="@id"/>
   <xsl:value-of select="side-name"/>
  </h2>
  <xsl:apply-templates select="line"/>
 </xsl:template>

 <!-- Line -->

 <xsl:template match="line">
  <xsl:variable name="curLine" select="line-num"/>
  <h3>
   <xsl:copy-of select="@id"/>
   <xsl:text>Line </xsl:text>
   <xsl:value-of select="line-num"/>
  </h3>
  <xsl:call-template name="drawGlyphLine"/>
 </xsl:template>

 <!-- Glyphs-->

 <xsl:template name="drawGlyphLine">
  <p>
   <xsl:text>Glyphs: </xsl:text>
   <xsl:value-of select="count(glyph/image[@type=$display-type])"/>
  </p>
  <div>
   <xsl:attribute name="height">
    <xsl:value-of select="160"/>
   </xsl:attribute>
   <xsl:attribute name="width">
    <xsl:value-of select="svg-width[@type=$display-type]"/>
   </xsl:attribute>
   <xsl:apply-templates select="glyph/image[@type=$display-type]"/>
  </div>
 </xsl:template>

 <!-- Glyph image -->

<xsl:template match="glyph/image">
 <svg>
     <g>
        <xsl:copy-of select="glyph/image/following-siblings::image[1]/path"> <!--Here I want previous sibling of path-->
        </xsl:copy-of>
     </g>
     <g>
     <xsl:copy-of select="path"> <!-- This line is making the output a copy of path-->
     </xsl:copy-of>
     </g>
     <g>
        <xsl:copy-of select="glyph/image/preceding-sibling::image[1]/path"> <!--Here I want next sibling of path-->
        </xsl:copy-of>
     </g>
  </svg>
 </xsl:template>

</xsl:stylesheet>

In the output, I want the following sibling of a current path. I have not added the full code cause of not making it unnecessarily long. Basically, full code automatically makes a copy of the path and renders the SVG. Now I just want the next and previous sibling.

Now the output should be like this.

<svg>
  <!-- previous path node -->

  <path id="path-1" d=""/>
  <x>7.6107272</x>
  <y>21.662689</y>
  <width>52.389273</width>
  <height>55.234216</height>

  <!-- next path node-->
</svg>
<svg>
  <!-- previous path node -->
  <path id="path-2" d=""/>
  <x>7.6107272</x>
  <y>21.662689</y>
  <width>52.389273</width>
  <height>55.234216</height>
  <!-- next path node -->
</svg>
<svg>
  <!-- previous path node -->
  <path id="path-3" d=""/>
  <x>7.6107272</x>
  <y>21.662689</y>
  <width>52.389273</width>
  <height>55.234216</height>
  <!-- next path node -->
</svg>
<svg>
  <!-- previous path node -->
  <path id="path-4" d=""/>
  <x>7.6107272</x>
  <y>21.662689</y>
  <width>52.389273</width>
  <height>55.234216</height>
  <!-- next path node -->
</svg>
<svgg>
  <!-- previous path node -->
  <path id="path-5" d=""/>
  <x>7.6107272</x>
  <y>21.662689</y>
  <width>52.389273</width>
  <height>55.234216</height>
  <!-- next path node -->
<svg>

解决方案

Your example has unique image IDs. However, if you want to traverse forwards and backwards, you can use the preceding axis. That is, if it is not causing any performance issues.

In your glyph/image template, store the @id first in a variable

<xsl:variable name="curr_id" select="@id"/>

then use that as you traverse in either preceding or following axis

 preceding::image[@id=$curr_id][1]/path
 following::image[@id=$curr_id][1]/path

Your template should look like this:

<xsl:template match="glyph/image">
    <xsl:variable name="curr_id" select="@id"/>
    <svg>
        <g>
            <xsl:copy-of select="preceding::image[@id=$curr_id][1]/path"> <!--Here I want previous sibling of path-->
            </xsl:copy-of>
        </g>
        <g>
            <xsl:copy-of select="path"> <!-- This line is making the output a copy of path-->
            </xsl:copy-of>
        </g>
        <g>
            <xsl:copy-of select="following::image[@id=$curr_id][1]/path"> <!--Here I want next sibling of path-->
            </xsl:copy-of>
        </g>
    </svg>
</xsl:template>

I have modified your example in the following link (http://xsltransform.net/pPgCH6G). That should do it if my assumptions are right.

这篇关于如何使用子节点的 xslt 从 xml 获取以下兄弟节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆