1

I'm writing an application in C# using .NET Framework 3.5 to implement a series of transforms. I'm using the XslCompiledTransform class to perform the transforms. I'd like to avoid writing a bunch of for-each statements in my XSLT transforms so I'd like to select some data based on an attribute. My source data looks as follows.

<Radios>
      <Radio name="UHF1">
        <GUID protected="true">785A9539-918B-4DCE-A9AA-AC9D6275EA86</GUID>
        <DigitalAudioDeviceInstance protected="true">1</DigitalAudioDeviceInstance>
        <DigitalAudioDevicePort>2</DigitalAudioDevicePort>
        <ACIMLocalInstance protected="true">1</ACIMLocalInstance>
        <ACIMLocalPort>2</ACIMLocalPort>
        <ACIMSCCInstance protected="true">1</ACIMSCCInstance>
      </Radio>
      <Radio name="VHF1">
        <GUID protected="true">C150EA26-E53E-4366-B4A0-84BF619BFD3A</GUID>
        <DigitalAudioDeviceInstance protected="true">2</DigitalAudioDeviceInstance>
        <DigitalAudioDevicePort>2</DigitalAudioDevicePort>
        <ACIMLocalInstance protected="true">2</ACIMLocalInstance>
        <ACIMLocalPort>6</ACIMLocalPort>
        <ACIMSCCInstance protected="true">2</ACIMSCCInstance>
      </Radio>
    </Radios>

I'm using the following to trying to reference the "ACIMSCCInstance" from a Radio:

<xsl:value-of select="Radios/Radio/ACIMSCCInstance[@name=UHF1]"/>

This is not working however Keep in mind that "Radios" is NOT the root of the document, and I am in fact at the appropriate level where this relative path should work. Just to make sure I tried this:

<xsl:value-of select="Radios/Radio/ACIMSCCInstance"/>

Which of course gives me the "ACIMSCCInstance" value ("1") of the first radio in the list.

My Question is, why doesn't the "[@name=UHF1]" at the end of the path work at picking the radio with the name "UHF1". I've also tried this "@name='UHF1']" and no dice.

1
  • Good question, +1. See my answer for an explanation of the problems and a complete solution. :) Commented Nov 6, 2010 at 1:44

1 Answer 1

5

I'm using the following to trying to reference the "ACIMSCCInstance" from a Radio:

<xsl:value-of select="Radios/Radio/ACIMSCCInstance[@name=UHF1]"/>

This is not working however

My Question is, why doesn't the "[@name=UHF1]" at the end of the path work at picking the radio with the name "UHF1

The XPath expression:

Radios/Radio/ACIMSCCInstance[@name=UHF1]

selects all ACIMSCCInstance elements whose name attribute is equal to the string value of at least one of the children-elements of ACIMSCCInstance that are named UHF1. Also this ACIMSCCInstance element must be a child of a Radio element and this must be a child of an Radios element and this must be a child of the current node.

There are at least two serious mistakes in this expression:

  1. There isn't any element named UHF1 in the whole document. You want to compare with the string literal 'UHF1' and string literals in XPath must be surrounded by either single or double quotes.

  2. No ACIMSCCInstance element in the document has a name attribute. You actually want this test to be done for the Radio element.

Solution:

Fixing the two problems above gives us the following correct XPath expression:

Radios/Radio[@name='UHF1']/ACIMSCCInstance

Recommendation: Reading a good book on XPath is necessary for acquiring the basic knowledge necessary for working with XSLT.

Sign up to request clarification or add additional context in comments.

3 Comments

+1 for helpful answer. 2 things: (1) in the upper middle you have a typo, UHF instead of UHF1. (2) @Ultratrunks: this mistake of forgetting the quotes and (in effect) accidentally using an element name that doesn't exist is an insidious problem of XPath. Most programming languages would throw an error, "No such variable UHF1". But XPath can't detect that your input document has no UHF1 element, unless it knows about the structure of the input document. For this you need a schema-aware XSLT dev environment.
@LarsH: Thanks for this observation -- I edited my answer. As for the benefits of SA XSLT/XPath, yes, they are really nice. My observations show that SA is being embraced very slowly -- partly due to lack of free and good implementations, but even more due to lack of knowledge and experience among users.
Nice, this worked. Just a bone head mistake I couldn't see with my own two eyes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.