如何使用子字符串为兄弟节点应用模板以搜索匹配的节点

时间:2016-06-07 02:20:11

标签: xml xslt

我不确定为什么这个applly-templates不起作用,我在我的XSL文件中调用了一个模板来搜索一个元素来获得答案" YES"然后继续使用另一个模板,但它结束了,因为我似乎无法使下一个模板起作用。 (使用XSLT 1.0)

示例XML(这是一个较大的XML的摘录,只是为了向您展示一点)

<Properties>
    ...
    <benCut_1__1_ formula="">Yes</benCut_1__1_>
    <CTRRad_1__2_ formula="">Yes</CTRRad_1__2_>
    <CBlRad_1__2_ formula="">Yes</CBlRad_1__2_>
    <CBRRad_1__2_ formula="">Yes</CBRRad_1__2_>
    <CTLRad_1__2_ formula="">Yes</CTLRad_1__2_>
    <CBlRad_1__3_ formula="">Yes</CBlRad_1__3_>
    <CBRRad_1__3_ formula="">Yes</CBRRad_1__3_>
    <CTLRad_1__3_ formula="">Yes</CTLRad_1__3_>
    <CTRRad_1__3_ formula="">Yes</CTRRad_1__3_>
    <bencut_1__2_ formula="">Yes</bencut_1__2_>
    <benCut_2__1_ formula="">Yes</benCut_2__1_>
    <benCutH_2__1_ formula="">21mm</benCutH_2__1_>
    <benCutW_2__1_ formula="">21mm</benCutW_2__1_>
    <benCutx_2__1_ formula="">21mm</benCutx_2__1_>
    <benCutY_2__1_ formula="">21mm</benCutY_2__1_>
    <benCTR_2__1_ formula="">21mm</benCTR_2__1_>
    <benCTl_2__1_ formula="">21mm</benCTl_2__1_>
    ...
</Properties>

首先我应用模板来搜索任何&#34; benCut _&#34;或&#34; bencut _&#34;结果,因为数据出现在不同的情况下(这个问题与这个问题分开)。

<xsl:template match="Properties" >
        <xsl:apply-templates select="*[contains(translate(name(),'BENCUT','bencut'),'bencut_')]" />
</xsl:template>

然后我需要将下一个apply-templates运行到任何&#34; bencut _&#34;具有值&#34;是&#34;,并找到字符串的结尾(最后6个字符创建一个匹配的字符串,以便在XML中找到我需要作为一组提取并以不同方式呈现的其他值

<xsl:template match="*[contains(translate(name(),'BENCUT','bencut'),'bencut_')]" >
    <xsl:if test="text()='Yes'">
        <xsl:apply-templates select="following-sibling::*[contains(name(),substring(name(),string-length(name())-5))]" />
    </xsl:if>
</xsl:template>

这是它开始失败的地方,因为我需要检查&#34; bencut _&#34;的兄弟姐妹。包含相同尾部字符串的节点,它们可以在前面或后面 (我删除了我原来选择的&#39; follow-sibling :: [contains(name(),substring(name(),string-length(name()) - 5))] | preceding-sibling: : [contains(name(),substring(name(),string-length(name()) - 5)]&#39;尝试调试代码)

[也不确定为什么&#34; |&#34;在&#34;和&#34;如果有人对此有任何解释,那就不会了。

这是我将要运行的最终模板,它将格式化我发现的每个其他兄弟姐妹的样子。

<xsl:template match="following-sibling::*[contains(name(),substring(name(),string-length(name())-5))]" >
    <xsl:value-of select="name()" />
</xsl:template>

最终结果是找到所有匹配的尾巴&#34; _1__2 _&#34;例如,并且能够看到以下数据,例如CTRRad_1__2_是Cutout Top Right Radius。

抠图(1)部分(2); 右上半径 - 是的 左下半径 - 是的 镂空高度 - 21毫米 开口宽度 - 21毫米 ...

将有1到11个切口的1-3个切片,即33个可能的切口块。

1 个答案:

答案 0 :(得分:1)

很难理解你的问题到底是什么。首先你说:

  

它开始失败,因为我需要检查兄弟姐妹   “bencut_”节点包含相同的尾部字符串,它们可以是   

之前或之后
然后你说:

  

它识别出有我的模板的部分字符串   难倒,

以此为出发点:

XSLT 1.0

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

<xsl:template match="/Properties">
    <root>
         <xsl:apply-templates select="*[starts-with(translate(name(), 'BENCUT', 'bencut'), 'bencut_')][.='Yes']" />
    </root>
</xsl:template>

<xsl:template match="*[starts-with(translate(name(), 'BENCUT', 'bencut'), 'bencut_')]">
    <xsl:variable name="key" select="substring(name(), string-length(name()) - 5)" />
    <group key="{$key}">
        <xsl:apply-templates select="../*[contains(name(), $key)]" mode="group"/>
    </group>
</xsl:template>

<xsl:template match="*" mode="group">
    <xsl:copy-of select="." />
</xsl:template>

</xsl:stylesheet>

应用于您的输入示例,结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <group key="_1__1_">
      <benCut_1__1_ formula="">Yes</benCut_1__1_>
   </group>
   <group key="_1__2_">
      <CTRRad_1__2_ formula="">Yes</CTRRad_1__2_>
      <CBlRad_1__2_ formula="">Yes</CBlRad_1__2_>
      <CBRRad_1__2_ formula="">Yes</CBRRad_1__2_>
      <CTLRad_1__2_ formula="">Yes</CTLRad_1__2_>
      <bencut_1__2_ formula="">Yes</bencut_1__2_>
   </group>
   <group key="_2__1_">
      <benCut_2__1_ formula="">Yes</benCut_2__1_>
      <benCutH_2__1_ formula="">21mm</benCutH_2__1_>
      <benCutW_2__1_ formula="">21mm</benCutW_2__1_>
      <benCutx_2__1_ formula="">21mm</benCutx_2__1_>
      <benCutY_2__1_ formula="">21mm</benCutY_2__1_>
      <benCTR_2__1_ formula="">21mm</benCTR_2__1_>
      <benCTl_2__1_ formula="">21mm</benCTl_2__1_>
   </group>
</root>

P.S。

效率更高的版本会使用

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

<xsl:key name="elem-by-tail" match="*" use="substring(name(), string-length(name()) - 5)" />

<xsl:template match="/Properties">
    <root>
         <xsl:apply-templates select="*[starts-with(translate(name(), 'BENCUT', 'bencut'), 'bencut_')][.='Yes']" />
    </root>
</xsl:template>

<xsl:template match="*[starts-with(translate(name(), 'BENCUT', 'bencut'), 'bencut_')]">
    <xsl:variable name="key" select="substring(name(), string-length(name()) - 5)" />
    <group key="{$key}">
        <xsl:apply-templates select="key('elem-by-tail', $key)" mode="group"/>
    </group>
</xsl:template>

<xsl:template match="*" mode="group">
    <xsl:copy-of select="." />
</xsl:template>

</xsl:stylesheet>