使用XSL从属性值中删除星号和单引号

时间:2012-04-28 07:08:08

标签: string xslt

我有这个XML片段:

<svrl:successful-report test="."
location="/*[local-name()='ClinicalDocument']/*[local-name()='component']/*[local-name()='structuredBody']/*[local-name()='component'][1]/*[local-name()='section']">

我想获取值@location并删除特殊字符" *[local-name()=' "" '] "。换句话说,我希望输出为

/ClinicalDocument/component/structuredBody/component[1]/section

我目前正在使用此字符串替换模板:

<xsl:template name="string-replace-all">
<xsl:param name="text" />
<xsl:param name="replace" />
<xsl:param name="by" />
<xsl:choose>
  <xsl:when test="contains($text, $replace)">
    <xsl:value-of select="substring-before($text,$replace)" />
    <xsl:value-of select="$by" />
    <xsl:call-template name="string-replace-all">
      <xsl:with-param name="text"
      select="substring-after($text,$replace)" />
      <xsl:with-param name="replace" select="$replace" />
      <xsl:with-param name="by" select="$by" />
    </xsl:call-template>
  </xsl:when>
  <xsl:otherwise>
    <xsl:value-of select="$text" />
  </xsl:otherwise>
</xsl:choose>
</xsl:template>

并应用这样的模板

                <xsl:call-template name="string-replace-all">
                <xsl:with-param name="text" select="@location"/>
                 <xsl:with-param name="replace" select="'[local-name()='"/>
                 <xsl:with-param name="by" select="''"/>         
            </xsl:call-template>    

只能得出这个结果:

/*'ClinicalDocument']/*'component']/*'structuredBody']/*'component'][1]/*'section']

如何获得我想要的输出?

2 个答案:

答案 0 :(得分:0)

你需要做两个“找到并替换”#39;这里。首先,您需要删除所有前缀 * [local-name()=&#39; ,然后您需要删除&#39;] 的后缀

您可以将第一个调用模板的结果作为参数传递给第二个调用模板

来执行此操作

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:svrl="my:my">
   <xsl:template match="svrl:successful-report">
      <xsl:call-template name="string-replace-all">
         <xsl:with-param name="text">
            <xsl:call-template name="string-replace-all">
               <xsl:with-param name="text" select="@location"/>
               <xsl:with-param name="replace" select="&quot;*[local-name()='&quot;"/>
               <xsl:with-param name="by" select="''"/>
            </xsl:call-template>
         </xsl:with-param>
         <xsl:with-param name="replace" select="&quot;']&quot;"/>
         <xsl:with-param name="by" select="''"/>
      </xsl:call-template>
   </xsl:template>

   <xsl:template name="string-replace-all">
      <xsl:param name="text"/>
      <xsl:param name="replace"/>
      <xsl:param name="by"/>
      <xsl:choose>
         <xsl:when test="contains($text, $replace)">
            <xsl:value-of select="substring-before($text,$replace)"/>
            <xsl:value-of select="$by"/>
            <xsl:call-template name="string-replace-all">
               <xsl:with-param name="text" select="substring-after($text,$replace)"/>
               <xsl:with-param name="replace" select="$replace"/>
               <xsl:with-param name="by" select="$by"/>
            </xsl:call-template>
         </xsl:when>
         <xsl:otherwise>
            <xsl:value-of select="$text"/>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>
</xsl:stylesheet>

应用于以下XML

<test xmlns:svrl="my:my">
   <svrl:successful-report test="." location="/*[local-name()='ClinicalDocument']/*[local-name()='component']/*[local-name()='structuredBody']/*[local-name()='component'][1]/*[local-name()='section']"/>
</test>

以下是输出

/ClinicalDocument/component/structuredBody/component[1]/section

答案 1 :(得分:0)

这个问题的另一个答案很好,但是像这样的源XML文档存在问题

<test xmlns:svrl="my:my">
 <svrl:successful-report test="." location=
 "/*[local-name()='ClinicalDocument']/*[local-name()='component'][.='abc']"/>
</test>

应用于此文档时产生的结果是:

   /ClinicalDocument/component[.='abc

但正确的结果是:

 /ClinicalDocument/component[.='abc']

此转换对上述XML文档没有任何问题

<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="@location">
  <xsl:attribute name="location">
    <xsl:call-template name="makeExplicit">
     <xsl:with-param name="pText" select="substring(.,2)"/>
    </xsl:call-template>
  </xsl:attribute>
 </xsl:template>

 <xsl:template name="makeExplicit">
  <xsl:param name="pText" select="."/>
  <xsl:if test="$pText">
   <xsl:variable name="vStep" select="substring-before(concat($pText, '/'), '/')"/>
   <xsl:call-template name="processStep">
     <xsl:with-param name="pStep" select="$vStep"/>
   </xsl:call-template>
   <xsl:call-template name="makeExplicit">
     <xsl:with-param name="pText" select="substring-after($pText, '/')"/>
   </xsl:call-template>
  </xsl:if>
 </xsl:template>

 <xsl:template name="processStep">
  <xsl:param name="pStep"/>
  <xsl:text>/</xsl:text>
  <xsl:value-of select="substring-before(concat($pStep, '*['), '*[')"/>

  <xsl:variable name="vPred" select="substring-after($pStep, '*[local-name()=')"/>
  <xsl:value-of select="substring-before(substring($vPred, 2), &quot;'&quot;)"/>
  <xsl:value-of select="substring-after($vPred, ']')"/>
 </xsl:template>
</xsl:stylesheet>

在上述文档中应用时,会产生正确的,想要的结果

<test xmlns:svrl="my:my">
   <svrl:successful-report test="." 
      location="/ClinicalDocument/component[.='abc']"/>
</test>