1

I'm trying to get data from a XML using like filter the fields that comes listed in an XML parameter in XSL: The parameter is a xml like this:

<Catalog name="Catalog1">
    <Fields>
        <Field>ID</Field>
        <Field>Name</Field>
        <Field>Description</Field>
    </Fields>
</Catalog>

So I need to retrieve this elements from another XML like this one:

<?xml version="1.0" encoding="UTF-8"?>
<Nodes>
    <Node>
        <Data>
            <Attribute name="ID">Desktop</Attribute>
            <Attribute name="Parent">administrator</Attribute>
            <Attribute name="Name">Desktop</Attribute>
            <Attribute name="Description">Desktop folder</Attribute>
        </Data>
        <Relationship>
            <RelatedNodes>
                <Node>
                    <Data>
                        <Attribute name="ID">administrator</Attribute>
                        <Attribute name="Parent"></Attribute>
                        <Attribute name="Name">administrator</Attribute>
                        <Attribute name="Description">administrator folder</Attribute>
                    </Data>
                </Node>
            </RelatedNodes>
        </Relationship>
    </Node>
</Nodes>

What I have so far is an XSL template like this one:

<?xml version="1.0"?>
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' >
    <xsl:output method='text'  encoding="UTF-8"/>
    <xsl:param name="Fields"> <!--type="xml"--></xsl:param>
    <xsl:template match="/">
        {
        <xsl:apply-templates select="//Data[Attribute[@name='Parent']='' ]/parent::Node" />
        }
    </xsl:template>

    <xsl:template match="Node" >
        "children":[
            {
                <xsl:for-each select="$Fields/Catalog/Fields/Field">
                    <xsl:variable name="AttributeName" select="." />
                    "<xsl:value-of select="$AttributeName"/>": " <xsl:value-of select="Data/Attribute[@name=$AttributeName]" /> ",
                </xsl:for-each>
                <xsl:apply-templates select="ancestor::Node[1]"/>
            }
        ]
    </xsl:template>
</xsl:stylesheet>

But is not working, the xpath is not getting the value, I think that is because I have to set the "'" character in the filter of the xpath that is why I was using concat but the concat just returned me the xpath as a string, any ideas?, The result should be like:

{
    "children":[
        {
            "ID": "1",
            "Name": "Name1",
            "Description: "Desc1",
        }
    ]
}

Thanks!

user2516482
  • 15
  • 1
  • 4

2 Answers2

1

Because you are only showing part of your problem I can only guess. Seems that you have some Data/Attribute entries in your XML. To access them you should not use concat in your select like you did.

Try something like:

    <xsl:for-each select="$Fields/Catalog/Fields/Field">
        <xsl:variable name="name" select="." />
        "<xsl:value-of select="."/>": " <xsl:value-of select="//Data/Attribute[@name= $name]" /> ",
    </xsl:for-each>
hr_117
  • 9,589
  • 1
  • 18
  • 23
1

If your dynamic paths consist simply of an element name, then you can use

*[name()=$path]

If they are more general paths then you need a function to evaluate an XPath expression supplied dynamically as a string. There's no such function in the standard until XSLT 3.0, but many XSLT processors have a suitable extension function, typically called xx:evaluate() where xx is some vendor prefix.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164