How to display all the ancestors and their attributes of a selected element?

A

ai2003lian

Assuming I have the following two xml file:


source.xml:

<AllFields>
<Group name="G1">
<Field fieldName="f1">Value1</Field>
<Field fieldName="f2">Value2</Field>
<Field fieldName="f3">Value3</Field>
</Group>
<Group name="G2">
<Field fieldName="f4">Value4</Field>
<Field fieldName="f5">Value5</Field>
<Field fieldName="f6">Value6</Field>
</Group>
<Group name="G3">
<Field fieldName="f7">Value7</Field>
<Field fieldName="f8">Value8</Field>
<Field fieldName="f9">Value9</Field>
</Group>
</AllFields>

requ­ired.xml:

<RequiredFields>
<FieldName>f1</FieldName>
<FieldName>f3</FieldName>
<FieldName>f6</FieldName>
</RequiredFields>


The requirement.xml defines which field will go to the output XML.

The xsl file and output XML are like the following:

xsl file:

<xsl:template match="node()|@*">
<xsl:if test="(not(self::Field )or
@FieldName=document('requ­ired.xml')/*/FieldName">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:if>
</xsl:template>

output.xml

<AllFields>
<Group name="G1">
<Field fieldName="f1">Value1</Field>

<Field fieldName="f3">Value3</Field>
</Group>
<Group name="G2">


<Field fieldName="f6">Value6</Field>
</Group>
<Group name="G3">



</Group>
</AllFields>


How could I use XSLT to get the following desired output(without all
the empty lines and the last Group element:


<AllFields>
<Group name="G1">
<Field fieldName="f1">Value1</Field>
<Field fieldName="f3">Value3</Field>
</Group>
<Group name="G2">
<Field fieldName="f6">Value6</Field>
</Group>
</AllFields>


Thanks your help in advance!
 
J

Joris Gillis

Tempore 23:06:17 said:
<xsl:template match="node()|@*">
<xsl:if test="(not(self::Field )or
@FieldName=document('requ­ired.xml')/*/FieldName">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:if>
</xsl:template>

How could I use XSLT to get the following desired output(without all
the empty lines and the last Group element:

try something like:

<xsl:template match="node()|@*">
<xsl:if test="not(self::Field or self::Group)
or (.|*)/@fieldName=document('requ­ired.xml')/*/FieldName">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:if>
</xsl:template>

(do beware of lower/uppercase, when you're testing this)

As for the whitespaces in your output, I don't see them occurring when I try your template.


regards,
 
A

ai2003lian

Thank. But it didn't work. The result xml is as the following:

<?xml version="1.0"?>
<AllFields>



</AllFields>

Any ideas?
 
J

Joris Gillis

Thank. But it didn't work. The result xml is as the following:

<?xml version="1.0"?>
<AllFields>



</AllFields>

Any ideas?

Very strange...

Tested with Saxon and AltovaXSLT

input:
<AllFields>
<Group name="G1">
<Field fieldName="f1">Value1</Field>
<Field fieldName="f2">Value2</Field>
<Field fieldName="f3">Value3</Field>
</Group>
<Group name="G2">
<Field fieldName="f4">Value4</Field>
<Field fieldName="f5">Value5</Field>
<Field fieldName="f6">Value6</Field>
</Group>
<Group name="G3">
<Field fieldName="f7">Value7</Field>
<Field fieldName="f8">Value8</Field>
<Field fieldName="f9">Value9</Field>
</Group>
</AllFields>

required.xml:
<RequiredFields>
<FieldName>f1</FieldName>
<FieldName>f3</FieldName>
<FieldName>f6</FieldName>
</RequiredFields>

XSL:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:strip-space elements="*"/>
<xsl:eek:utput method="xml" indent="yes"/>

<xsl:template match="node()|@*">
<xsl:if test="not(self::Field or self::Group)
or (.|*)/@fieldName=document('required.xml')/*/FieldName">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

(notice the 'strip-space' element I added; it solves the issue with the
linebreaks.

output:

<AllFields>
<Group name="G1">
<Field fieldName="f1">Value1</Field>
<Field fieldName="f3">Value3</Field>
</Group>
<Group name="G2">
<Field fieldName="f6">Value6</Field>
</Group>
</AllFields>


The stylesheet probably needed adaption to your real XML. It's probably
some wrong names in the test expression that cause the trouble with your
real XML.
 
A

ai2003lian

Thanks. It still didn't work for me since I'm using XML C parser
libxml2 and libxslt. But I came up with the following solution:

<xsl:eek:utput method = "xml" indent = "yes" />

<xsl:template match="node()">
<xsl:if
test="descendant-or-self::*/@fieldName=document('required.xml')/*/FieldName
or @FieldName=document('requ­ired.xml')/*/FieldName">
<xsl:text>
</xsl:text>
<xsl:element name = "{name(self::*)}" >
<xsl:for-each select = "@*" >
<xsl:attribute name="{name(current())}" >
<xsl:value-of select = "current()" />
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="node()"/>
<xsl:value-of select = "node()" />
</xsl:element>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

It works fine although I'm still looking for a better way to do it.
 
J

Joris Gillis

Thanks. It still didn't work for me since I'm using XML C parser
libxml2 and libxslt. But I came up with the following solution:

<xsl:eek:utput method = "xml" indent = "yes" />

<xsl:template match="node()">
<xsl:if
test="descendant-or-self::*/@fieldName=document('required.xml')/*/FieldName
or @FieldName=document('requ­ired.xml')/*/FieldName">
<xsl:text>
</xsl:text>
<xsl:element name = "{name(self::*)}" >
<xsl:for-each select = "@*" >
<xsl:attribute name="{name(current())}" >
<xsl:value-of select = "current()" />
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="node()"/>
<xsl:value-of select = "node()" />
</xsl:element>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

It works fine although I'm still looking for a better way to do it.

how about this template?

<xsl:template match="node()">
<xsl:if
test="descendant-or-self::*/@fieldName=document('required.xml')/*/FieldName">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node()"/>
<xsl:value-of select="text()" />
</xsl:copy>
</xsl:if>
</xsl:template>

(correct result in Saxon), just curious to know if your processor can
handle this...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top