1
votes

I need an XPath expression that does the following:

  • If the context node is not the first child, it returns blank
  • If the context node is the first child then the expression should return the value of a "temp" node elsewhere in the document
    • In this example that value would be <my:DisplayNameTemp>Green, John</my:DisplayNameTemp>
  • InfoPath only supports XPath 1.0 and does not support "Position" expressions
  • I am using MS InfoPath and will use rules to apply this expression if more than one child node is detected.

I am trying to blank a people picker in MS InfoPath if more than one user is selected. Here is my sample XML:

<?xml version="1.0" encoding="UTF-8"?><?mso-infoPathSolution solutionVersion="1.0.0.24" productVersion="14.0.0" PIVersion="1.0.0.0" href="file:///C:\Documents%20and%20Settings\Chris\Local%20Settings\Application%20Data\Microsoft\InfoPath\Designer3\35e8a7eff4a841a9\manifest.xsf" ?><?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.2"?>
<my:myFields xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pc="http://schemas.microsoft.com/office/infopath/2007/PartnerControls" xmlns:ma="http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes" xmlns:d="http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields" xmlns:q="http://schemas.microsoft.com/office/infopath/2009/WSSList/queryFields" xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution" xmlns:dms="http://schemas.microsoft.com/office/2009/documentManagement/types" xmlns:tns="http://microsoft.com/webservices/SharePointPortalServer/UserProfileService" xmlns:s1="http://microsoft.com/wsdl/types/" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-09-06T15:09:43" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003" xml:lang="en-us">
    <my:group>
        <pc:Person xmlns:pc="http://schemas.microsoft.com/office/infopath/2007/PartnerControls">
            <pc:DisplayName>Green, John</pc:DisplayName>
            <pc:AccountId>DOMAIN\John.Green</pc:AccountId>
            <pc:AccountType>User</pc:AccountType>
        </pc:Person><pc:Person xmlns:pc="http://schemas.microsoft.com/office/infopath/2007/PartnerControls">
            <pc:DisplayName>Smith, John</pc:DisplayName>
            <pc:AccountId>DOMAIN\john.smith</pc:AccountId>
            <pc:AccountType>User</pc:AccountType></pc:Person>
        <pc:Person xmlns:pc="http://schemas.microsoft.com/office/infopath/2007/PartnerControls">
            <pc:DisplayName>Public, John</pc:DisplayName>
            <pc:AccountId>DOMAIN\John.Q.Public</pc:AccountId>
            <pc:AccountType>User</pc:AccountType>
        </pc:Person><pc:Person xmlns:pc="http://schemas.microsoft.com/office/infopath/2007/PartnerControls">
            <pc:DisplayName>Doe, John</pc:DisplayName>
            <pc:AccountId>DOMAIN\John.Doe</pc:AccountId>
            <pc:AccountType>User</pc:AccountType></pc:Person>
    </my:group>
    <my:DisplayNameTemp>Green, John</my:DisplayNameTemp>
    <my:AccountIdTemp>DOMAIN\John.Green</my:AccountIdTemp>
    <my:AccountTypeTemp>User</my:AccountTypeTemp>
</my:myFields>

If I can return a "blank" value for all but the first child then the picker will revalidate after the user takes focus off of it and only one username will be present.

I can use the following expression to retrieve the first user that was chosen with the picker: //my:group/pc:Person[1]/pc:DisplayName.

  • I believe that I need an expression which utilizes the | command and the expression just mentioned above for the first child, or simply a "" for anything else.
  • I believe that checking for the existence of a node in the preceding sibling might reveal which node is first without using any position expressions.

    I can't quite cobble it together.

1
Chris- What exactly is your context node here? The "first child" of what?JWiley
Chris, if "position expressions" aren't supported, than XPath 1.0 isn't supported.Dimitre Novatchev
@Jwiley Sorry for the lack of context; this expression is intended to be "housed" as the default value for the displayname node in MS InfoPath. MS InfoPath will then use the return value of this expression and place it in the displayname node. I hope that helps clarify!Shrout1
@DimitreNovatchev MS InfoPath only supports certain aspects of XPath... You'd have to ask them.Shrout1

1 Answers

0
votes

Use:

concat($yourTempNode[not($yourContextNode/preceding-sibling::*)], 
       substring(' ', 1 + boolean($yourContextNode/preceding-sibling::*))
       )

The first argument of concat() is the value of $yourTempNode -- if $yourContextNode has no preceding sibling element or nothing otherwise.

The second argument is a cpace character -- if $yourContextNode isn't the first child element of its parent or otherwize nothing.