سؤال

I'm stuck trying to wrote an XSLT that will select items with an category of "Featured", because the data inside category is wrapped in a CDATA.

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:template match="/">
        <html>
          <body>
            <h2>Matched Items</h2>
            <xsl:apply-templates select="//item[category/.='Featured']"/>
          </body>
        </html>
      </xsl:template>

      <xsl:template match="item">
        <div class="news-item" width="100%">
          <div class="news-item-description">
            <xsl:value-of select="description"/>
          </div>
        </div>
        <div class="clear" />
      </xsl:template>
    </xsl:stylesheet>

Here is a sample of my data. This is from a wordpress blog, so I cannot change the output.

    <items>
      <item>
        <category>
          <![CDATA[ Category A ]]>
        </category>
        <category>
          <![CDATA[ Featured ]]>
        </category>
        <description>This item should be in the output HTML</description>
      </item>
      <item>
        <category>
          <![CDATA[ Uncategorized ]]>
        </category>
        <category>
          <![CDATA[ Some other category ]]>
        </category>
        <description>This item should NOT be in the output HTML</description>
      </item>
      <item>
        <category>
          <![CDATA[ Uncategorized ]]>
        </category>
        <category>
          <![CDATA[ Featured ]]>
        </category>
        <description>This item should be in the output HTML</description>
      </item>
    </items>

The output I want looks like this:

    <html>
    <body>
    <h2>Matched Items</h2>
    <div class="news-item" width="100%">
    <div class="news-item-description">This item should be in the output HTML</div>
    </div>
    <div class="clear"></div>
    <div class="news-item" width="100%">
    <div class="news-item-description">This item should be in the output HTML</div>
    </div>
    <div class="clear"></div>
    </body>
    </html>

This seems like it should be easy. The combination of multiple category elements plus the CDATA wrapper has me stuck. Thanks

هل كانت مفيدة؟

المحلول

//item[category/.='Featured'] is not even syntactically valid XPath, I assume that is a typo.

In any case, this is not about CDATA. CDATA is meaningless, it does not exist. It only matters during parsing of a document. When you get to use XPath on the input it is already gone.

You need to trim whitespace before you make string comparisons. Try:

<xsl:apply-templates select="//item[category[normalize-space() = 'Featured']]" />

نصائح أخرى

As Tomalak pointed out the XPath you have isn't valid, and probably caused issues even running the XSLT. Tomalaks is probably the answer you are looking for, but if you aren't sure if featured might be within, but not the only text within, the category you could also use the contains() XPath function, like so:

<xsl:apply-templates select="//item[category[contains(text(),'Featured')]]"/>

If you change the apply-templates line in your XSLT this should work as expected.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top