1

我有这个 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']

我怎样才能得到我想要的输出?

4

2 回答 2

0

您需要在这里进行两次“查找和替换”。首先,您需要删除所有前缀*[local-name()=',然后您需要删除']的后缀

您可以通过将第一个调用模板的结果作为参数传递给第二个调用模板来做到这一点

这是完整的 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
于 2012-04-28T08:04:53.810 回答
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>
于 2012-04-28T14:40:24.247 回答