如何使用XSLT构建字符串?

问题描述:

我有这样的XML片段如何使用XSLT构建字符串?

<MediaTypes> 
    <DVD>true</DVD> 
    <HDDVD>false</HDDVD> 
    <BluRay>true</BluRay> 
</MediaTypes> 

我想创建一个输出看起来像这样

DVD/Blu-ray 

或类似这样的

DVD 

或类似这样的

DVD/HD-DVD/Blu-ray 

取决于真/假状态

但我是XSLT游戏中的总新手。 : -/

下面是完整的XML

<?xml version="1.0" encoding="Windows-1252"?> 
<Collection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <DVD> 
    <ProfileTimestamp>2012-06-07T05:20:51Z</ProfileTimestamp> 
    <ID>0044005507027.5</ID> 
    <MediaTypes> 
     <DVD>true</DVD> 
     <HDDVD>false</HDDVD> 
     <BluRay>false</BluRay> 
    </MediaTypes> 
    <UPC>0-044005-507027</UPC> 
    <CollectionNumber>448</CollectionNumber> 
    <CollectionType IsPartOfOwnedCollection="true">Owned</CollectionType> 
    <Title>The Big Lebowski</Title> 
    <DistTrait /> 
    <OriginalTitle /> 
    <CountryOfOrigin>United States</CountryOfOrigin> 
    ... 
    </DVD> 
    <DVD> 
    ... 
    </DVD> 
</Collection> 

我试图按照(关于循环)给出的建议的一个片断,但它似乎并没有工作。

这是XSL我到目前为止(完成):

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template name="MediaTypes" match="MediaTypes"> 
     Test 
     <xsl:for-each select="*[.='true']">    
      <xsl:value-of select="name()"/> 
      <xsl:if test="position()!=last()"> 
       <xsl:text>/</xsl:text> 
      </xsl:if> 
     </xsl:for-each>   
    </xsl:template> 

    <xsl:template match="/"> 
     <html> 
      <head> 
       <title>DVD Profiler Double Dips</title> 
      </head> 
      <body> 
       <div> 
        <h1>DVD Profiler Double Dips</h1> 
       </div> 
       <table border="1" cellpadding="3" cellspacing="0"> 
        <tr> 
         <th>Title</th> 
         <th>Edition</th> 
         <th>Production Year</th> 
         <th>DVD /</th> 
         <th>Purchase Date</th> 
         <th>Collection Type</th> 
         <th>Original Title</th> 
         <th>Sort Title</th> 
        </tr> 
        <xsl:for-each select="/Collection/DVD"> 
         <tr> 
          <td> 
           <xsl:value-of select="Title"/> 
          </td> 
          <td> 
           <xsl:if test="DistTrait != ''"> 
            <xsl:value-of select="DistTrait"/> 
           </xsl:if> 
           <xsl:if test="DistTrait = ''"> 
            &#160; 
           </xsl:if> 
          </td> 
          <td> 
           <xsl:if test="ProductionYear != ''"> 
            <xsl:value-of select="ProductionYear"/> 
           </xsl:if> 
           <xsl:if test="ProductionYear = ''"> 
            &#160; 
           </xsl:if> 
          </td> 
          <td> 
           <xsl:call-template name="MediaTypes" /> 
          </td> 
         </tr> 
        </xsl:for-each> 
       </table> 
      </body> 
     </html> 
    </xsl:template> 
</xsl:stylesheet> 

但是,在

<xsl:call-template name="MediaTypes" /> 

是站着的,只有 “测试” 出来

耶!

你们真棒。是

<xsl:apply-templates select="MediaTypes"/> 

是我选择的武器。

我最后的模板看起来是这样的:

<xsl:template name="MediaTypes" match="MediaTypes"> 
    <xsl:for-each select="*[.='true']"> 
     <xsl:value-of select="name()"/> 
     <xsl:if test="position()!=last()"> 
      <xsl:text>/</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
    <xsl:if test="CustomMediaType != ''"> 
     <xsl:if test="*[.='true']"> 
      <xsl:text>/</xsl:text> 
     </xsl:if> 
     <xsl:value-of select="CustomMediaType"/> 
    </xsl:if> 
</xsl:template> 

开始理解的东西是如何工作的

感谢您的帮助!

+0

XSLT的什么版本DVD/BluRay

测试?你可以使用2.0还是仅限于1.0,如果使用1.0,那么你将使用哪种XSLT处理器? –

+0

严,所以你想使用元素而不是他们的内容作为你的输出?这有点不同寻常 –

+0

@IanRoberts我想将这个XSL放入一个XML文件的头部,然后让任何浏览器向我展示一个HTML。 –

这个问题相当微不足道 - 真正的问题是您只能显示XML文档的片段。 XSLT非常依赖于上下文。

这是一个匹配任何<MediaTypes>元素并输出所需字符串的模板;希望你能知道如何将其纳入自己的样式表:

<xsl:template match="MediaTypes"> 
    <xsl:for-each select="*[.='true']"> 
     <xsl:value-of select="name()"/> 
     <xsl:if test="position()!=last()"> 
      <xsl:text>/</xsl:text> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:template> 
+0

我已经试过了,但它似乎没有进入for-each循环 我已经进入到我的代码,这 的 \t Test /的xsl:for-each>的 和稍后当我需要它,我写 的 但是唯一的输出是“Test”:-( –

+1

@ DeeJ.Doena您可能需要使用'apply-templates'而不是'call-template'来确保上下文节点是正确的 - 使用''上下文节点将保留在调用点的任何位置,但是使用'它会正确地将上下文重置到MediaTypes元素。 –

+0

@ DeeJ.Doena我建议你编辑你的问题来包含你的XSLT和你希望得到的输出(作为代码)。 –

我建议你更改XML有点

下面是一个例子

<?xml version="1.0" ?> 
<?xml-stylesheet type="text/xsl" ?> 
<MediaTypes> 
    <Media name="DVD">true</Media> 
    <Media name="HDDVD">false</Media> 
    <Media name="BluRay">true</Media> 
</MediaTypes> 

这样你可能会写入XPATH表达式,如//MediaTypes/Media 但是@michael。hor257k写一个很好的解决方案,这顶格局XML成看起来像这样

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="//MediaTypes"> 
     <xsl:for-each select="*[.='true']"> 
      <xsl:value-of select="@name"/> 
      <xsl:if test="position()!=last()"> 
       <xsl:text>/</xsl:text> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

这将使这里http://xslttest.appspot.com/

+0

谢谢,但遗憾的是XML不是我的: - / –