Hello,
My company makes a publication which outputs a clients current set of diagrams, You can search the publication for diagrams with a given attribute value.
This works but only if the value is contained in the first Attribute node.
Me and another fellow have been trying to fix it so that it searches all the attributes.
Here is the xsl snippet being used to search the attributes. It is looking in Folder Diagram and Shape Elements to see if a child Attribute element contains a the word entered by the user.
<xsl:template name="testObject">
<xsl:if test="(name() = 'Shape' and $includeShapes) or (name() = 'Folder' and $includeFolders) or (name() = 'Document' and $includeDocuments) or (name() = 'Diagram' and $includeDiagrams)">
<xsl:variable name="objXMLLocation">
<xsl:choose>
<xsl:when test="name() = 'Folder'">
<xsl:value-of select="concat(@ID, '/folder.xml')" />
</xsl:when>
<xsl:when test="name() = 'Document'">
<xsl:value-of select="concat(@ID, '/document.xml')" />
</xsl:when>
<xsl:when test="name() = 'Diagram'">
<xsl:value-of select="concat(@ID, '/diagram.xml')" />
</xsl:when>
<xsl:when test="name() = 'Shape'">
<xsl:value-of select="concat(../../@ID, '/', ../../@ID, '_files/', @Source)" />
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:if test="js:fileExists($objXMLLocation)">
<xsl:variable name="objXML" select="document($objXMLLocation)" />
<xsl:choose>
<xsl:when test="$searchName">
<xsl:if test="js:containsKeywords($objXML/*/Properties/RepositoryName, $searchKeywords)">
<xsl:apply-templates mode="render" select=".">
<xsl:with-param name="fullXML" select="$objXML" />
</xsl:apply-templates>
</xsl:if>
</xsl:when>
<xsl:when test="$searchDescription">
<xsl:if test="js:containsKeywords($objXML/*/Properties/Description, $searchKeywords)">
<xsl:apply-templates mode="render" select=".">
<xsl:with-param name="fullXML" select="$objXML" />
</xsl:apply-templates>
</xsl:if>
</xsl:when>
<xsl:when test="$searchAttributes">
<xsl:if test="name() != 'Folder'">
<xsl:if test="js:containsKeywords($objXML/*/CustomAttributes/Attribute/Value,$searchKeywords)">
<xsl:apply-templates mode="render" select=".">
<xsl:with-param name="fullXML" select="$objXML" />
</xsl:apply-templates>
</xsl:if>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:if>
</xsl:if>
</xsl:template>
Here is the Javascript function containsKeyword it looks to see if the substrings in the needle parameter which are search words entered by the user exists inside the haystack parameter which is the value of an element or attribute that the user is searching the publication for. I am myself unsure of what is going on exactly, but it appears to work correctly.
function containsKeywords(haystack, needles) {
var ks = needles[0].selectNodes('//K');
var n;
if (haystack[0].firstChild) {
n = haystack[0].firstChild.nodeValue.toUpperCase();
} else {
return 0;
}
for (var i = 0; i < ks.length; i++) {
if (n.indexOf(ks[i].firstChild.nodeValue) < 0) {
return 0;
}
}
return 1;
}
The xml being searched.
<Diagram ID="49ab6eb5-c51f-4e36-9495-869897ef0d0d">
<CustomAttributes>
<Attribute>
<Name>Approval Status</Name>
<Description>Document / Diagram / Object Approval Status</Description>
<Value>Draft - Work in Progress</Value>
<Datatype>Text</Datatype>
</Attribute>
<Attribute>
<Name>Next Document Review Date</Name>
<Description>When is this document to be reviewed next?</Description>
<Value />
<Datatype>Date</Datatype>
</Attribute>
<Attribute>
<Name>Stakeholder View</Name>
<Description>Select the Stakeholder View</Description>
<Value>PMO</Value>
<Datatype>Text</Datatype>
</Attribute>
The current xsl will render a link to the diagram if Draft is enter as it exists in the 1st Attribute element's Value child element. But searching for PMO will return nothing.
The problem is that the xsl will only look at the first Attribute element, when it needs to look at all the child elements in the CustomAttribute element.
We tried using a for-each to go through all the Attribute elements we had trouble traversing the xml tree to get the Diagram ancestor so that it could be selected for the render.
Thanks.