【问题标题】:Apply XSLT on XML to get Formatted (colour) Output在 XML 上应用 XSLT 以获取格式化(颜色)输出
【发布时间】:2010-08-16 00:16:11
【问题描述】:

如何将 XSLT 应用于以下 XML,以便 ~ 和 $ 之间的字符串在输出中变为红色。

当您只有一个包含 ~ 和 $ 的字符串时,以下 XSLT 工作。当您有多个包含 ~ 和 $ 的字符串时,它将不起作用。 信息 我正在为 DATAC 使用相同的模板'

我正在使用 Java 来比较字符串。

我可以选择更改 java 或 XSLT 中的代码。

谢谢

XML

   <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type='text/xsl' href='StyleSheet.xsl'?>
<log >
       <rows>
        <ID>1</ID>
        <DataP>
  BookID = UJ2445320A
  Qty =  1 ISBN = 45320A 
  ~publishDate = 1/1/2006 $
  ~Name =Learn XML $
  </DataP>
  <DataC>
  BookID = UJ2445320A
  Qty =  1 ISBN = 45320A 
  ~publishDate =2/2/2010$
  ~Name =Learn XML 1.0 $
  </DataC>
             </rows>
  </log>

XSLT

<xsl:for-each select="rows">
    <tr>
   <td><xsl:value-of select="ID"/></td>
   <xsl:apply-templates select="DataP"/>
   <xsl:apply-templates select="DataC"/>
   </tr>
  </xsl:for-each>
 </xsl:for-each>
</xsl:template>
   <xsl:template  match="DataP">  
  <xsl:choose>
   <xsl:when test="contains(.,'~')">
    <td>
     <xsl:value-of select="substring-before(.,'~')"/> 
     <span style="color:red;"><xsl:value-of select="substring-before(substring-after(.,'~'),'$')"/></span>
     <xsl:value-of select="substring-after(.,'$')"/>
    </td>
   </xsl:when>  
   <xsl:otherwise>   
    <td><xsl:value-of select="."/></td> 
   </xsl:otherwise>
  </xsl:choose>
 </xsl:template>

JAVA 代码

StringBuilder sbcp = new StringBuilder();
StringBuilder sbpp = new StringBuilder();
String[] spilt = StringUtils.split(DataC, "|");
String[] spilt2 = StringUtils.split(DataP, "|");

for (int i = 0; i < spilt.length; i++)
        {
            if(spilt2[i].toString().equals(spilt[i]))
            {
                sbcp.append(spilt[i]);
                sbpp.append(spilt2[i]);
            }
            else
            {
                sbcp.append("~").append(spilt[i]).append("$");
                sbpp.append("~").append(spilt2[i]).append("$");
            }
        }

【问题讨论】:

  • 好问题 (+1)。有关完整的 XSLT 1.0 解决方案,请参阅我的答案。 :)

标签: java xml xslt


【解决方案1】:

这是一个完整的 XSLT 1.0 解决方案

<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="/*">
  <table border="1">
   <xsl:apply-templates/>
    </table>
 </xsl:template>

 <xsl:template match="rows">
    <tr>
   <xsl:apply-templates/>
    </tr>
 </xsl:template>

 <xsl:template match="ID">
   <td><xsl:value-of select="."/></td>
 </xsl:template>

 <xsl:template  match="DataP|DataC">
  <td>
   <xsl:call-template name="formatText">
     <xsl:with-param name="pText" select="."/>
   </xsl:call-template>
  </td>
 </xsl:template>

 <xsl:template name="formatText">
  <xsl:param name="pText"/>
  <xsl:param name="pStartDelim" select="'~'"/>
  <xsl:param name="pEndDelim" select="'$'"/>

  <xsl:if test="string-length($pText)">
      <xsl:variable name="vText" select=
           "concat($pText, $pStartDelim)"/>
      <xsl:variable name="vBeforePat" select=
           "substring-before($vText, $pStartDelim)"/>
      <xsl:variable name="vInText" select=
       "substring-before(substring-after($vText, $pStartDelim),
                         $pEndDelim
                        )
      "/>

        <xsl:variable name="vExistsInText"
             select="string-length($vInText)"/>

     <xsl:value-of select="$vBeforePat"/>

     <xsl:if test="$vExistsInText">
      <span style="color:red;">
        <xsl:value-of select="$vInText"/>
      </span>

      <xsl:call-template name="formatText">
       <xsl:with-param name="pText" select=
        "substring($pText,
                   1
                   + string-length($vBeforePat)+1
                   + $vExistsInText
                   + boolean($vExistsInText) 
                   )
        "/>
      </xsl:call-template>
     </xsl:if>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于此 XML 文件时

<log>
    <rows>
        <ID>1</ID>
        <DataP>
  BookID = UJ2445320A
  Qty =  1 ISBN = 45320A
  ~publishDate = 1/1/2006 $;
  ~Name =Learn XML $
        </DataP>
        <DataC>
  BookID = UJ2445320A
  Qty =  1 ISBN = 45320A
  ~publishDate =2/2/2010$;
  ~Name =Learn XML 1.0 $
        </DataC>
    </rows>
</log>

产生所需的正确输出

<table border="1">
   <tr>
      <td>1</td>
      <td>
  BookID = UJ2445320A
  Qty =  1 ISBN = 45320A
  <span style="color:red;">publishDate = 1/1/2006 </span>;
  <span style="color:red;">Name =Learn XML </span>

      </td>
      <td>
  BookID = UJ2445320A
  Qty =  1 ISBN = 45320A
  <span style="color:red;">publishDate =2/2/2010</span>;
  <span style="color:red;">Name =Learn XML 1.0 </span>

      </td>
   </tr>
</table>

请注意文本的格式化是如何通过递归命名模板实现的。

【讨论】:

    【解决方案2】:

    我认为正则表达式可能是一种方法。你只需要构建'~ someString $' 模式并将它们变成红色。

    【讨论】:

      【解决方案3】:

      你可以试试xsl analyze string:

      <xsl:template  match="DataP">
        <xsl:analyze-string select="." regex="~(.*?)\$">
          <xsl:matching-substring>
             <span style="color:red;"><xsl:value-of select="regex-group(1)"/></span>
          </xsl:matching-substring>
          <xsl:non-matching-substring>
            <xsl:value-of select="."/>
          </xsl:non-matching-substring>
        </xsl:analyze-string>
      </xsl:template> 
      

      不确定正则表达式是否正确,您应该仔细检查。

      【讨论】:

      • 或许 ~([^$]*)\$ 会更好?
      猜你喜欢
      • 2023-03-09
      • 1970-01-01
      • 2011-06-25
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多