Altova Mailing List Archives>Archive Index >microsoft.public.xsl Archive Home >Recent entries >Thread Prev - Re: Combining elements [Thread Next] Re: Combining elementsTo: NULL Date: 4/1/2008 11:22:00 AM
"tshad" <tshad@d...> wrote in message
news:OUvUz6BlIHA.2368@T......
>
> "Martin Honnen" <mahotrash@y...> wrote in message
> news:eoQPgH$kIHA.6032@T......
>> tshad wrote:
>>
>>>
>>> What I would like the result to look like is:
>>> ************************************************************
>>> <?xml version="1.0" encoding="utf-8"?>
>>> <REPORT>
>>> <form>
>>> <sectionNumber>0</sectionNumber>
>>> <primary>True</primary>
>>> <formName>1004</formName>
>>> <tagName>OTHERFILENUMBER</tagName>
>>> <flags>0</flags>
>>> <format>0</format>
>>> <value>692</value>
>>> </form>
>>> <form>
>>> <sectionNumber>0</sectionNumber>
>>> <primary>True</primary>
>>> <formName>1004</formName>
>>> <tagName>FNMA_FILENUMBER</tagName>
>>> <flags>0</flags>
>>> <format>0</format>
>>> <value>693</value>
>>> </form>
>>> <form>
>>> <sectionNumber>0</sectionNumber>
>>> <primary>True</primary>
>>> <formName>1004</formName>
>>> <tagName>SUBPROPADDRESS</tagName>
>>> <flags>0</flags>
>>> <format>0</format>
>>> <value>3</value>
>>> </form>
>>> <form>
>>> <sectionNumber>0</sectionNumber>
>>> <primary>True</primary>
>>> <formName>1004</formName>
>>> <tagName>SCMCOMMENTS_1</tagName>
>>> <flags>0</flags>
>>> <format>0</format>
>>> <value>This is a test line 1 This is a test line 2 This is a test
>>> line 3 This is a test line 4</value>
>>> </form>
>>> <form>
>>> <sectionNumber>1</sectionNumber>
>>> <primary>True</primary>
>>> <formName>1004</formName>
>>> <tagName>FormFormats</tagName>
>>> <flags>0</flags>
>>> <format>0</format>
>>> <value>NUM=1 FORMCODE=1004 SECCODE=1 DESC= MAJOR=True</value>
>>> </form>
>>> </REPORT>
>>
>> Here is an adapted stylesheet that creates the output described above:
>>
>> <xsl:stylesheet
>> xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>> version="1.0">
>>
>> <xsl:output method="xml" indent="yes"/>
>>
>> <xsl:template match="REPORT">
>> <xsl:copy>
>> <xsl:apply-templates
>> select="FORMS/FORM/FIELDS/*[not(starts-with(name(), 'SCMCOMMENTS'))]"/>
>> <form>
>> <sectionNumber>0</sectionNumber>
>> <primary>True</primary>
>> <formName><xsl:value-of select="FORMS/FORM/@FORMCODE"/></formName>
>> <tagName>SCMCOMMENTS_1</tagName>
>> <flags>0</flags>
>> <format>0</format>
>> <value>
>> <xsl:apply-templates
>> select="FORMS/FORM/FIELDS/*[starts-with(name(), 'SCMCOMMENTS')]"/>
>> </value>
>> </form>
>> <form>
>> <sectionNumber>
>> <xsl:value-of select="FORMS/FORM/@SECCODE"/>
>> </sectionNumber>
>> <primary>True</primary>
>> <formName>
>> <xsl:value-of select="FORMS/FORM/@FORMCODE"/>
>> </formName>
>> <tagName>FormFormats</tagName>
>> <flags>0</flags>
>> <format>0</format>
>> <value>
>> <xsl:apply-templates select="FORMS/FORM/@*"/>
>> </value>
>> </form>
>> <xsl:apply-templates select="FORMS/FORM/attachments/attachment"/>
>> </xsl:copy>
>> </xsl:template>
>>
>> <xsl:template match="FIELDS/*[not(starts-with(name(), 'SCMCOMMENTS'))]">
>> <form>
>> <sectionNumber>
>> <xsl:text>0</xsl:text>
>> </sectionNumber>
>> <primary>True</primary>
>> <formName>
>> <xsl:value-of select="../../@FORMCODE"/>
>> </formName>
>> <tagName>
>> <xsl:value-of select="name()"/>
>> </tagName>
>> <flags>0</flags>
>> <format>0</format>
>> <value>
>> <xsl:value-of select="."/>
>> </value>
>> </form>
>> </xsl:template>
>>
>> <xsl:template match="FIELDS/*[starts-with(name(), 'SCMCOMMENTS')]">
>> <xsl:value-of select="."/>
>> <xsl:if test="position() != last()">
>> <xsl:text> </xsl:text>
>> </xsl:if>
>> </xsl:template>
>>
>> <xsl:template match="FORM/@*">
>> <xsl:value-of select="concat(name(), '=', .)"/>
>> <xsl:if test="position() != last()">
>> <xsl:text> </xsl:text>
>> </xsl:if>
>> </xsl:template>
>>
>> </xsl:stylesheet>
>>
>>
> This works perfect.
>
> I am just not sure I understand why. as normally we don't do anything in
> the first template except apply the next templates. This has always been
> a confusion with me on how the different templates work. I got a better
> idea when we did the concat of the attributes and put the apply-templates
> inside the 2nd template.
>
> In all my other ones, I always used the 1st template to apply the other
> templates, but did nothing in it.
>
> This one is different.
>
> I'll take a stab at what I think it is doing.
>
> 1) We get all the elements in the page. Since REPORT is the first
> element - we get that and all below it. We could also have done "/*", I
> believe - not sure about "/".
>
> 2) Not sure what the xsl:copy does, but then we apply-template that looks
> similar to "FORMS/FORM/FIELDS/*[not(starts-with(name(), 'SCMCOMMENTS'))]".
> The template actually is "FIELDS/*[not(starts-with(name(),
> 'SCMCOMMENTS'))]" which gets all the elements that don't start with
> SCMCOMMENTS and applys the template to each of those fields. Not sure why
> the one has FORMS/FORM/ in front of it and the other doesn't.
>
> 3) Then we do one element set that starts with SCMCOMMENTS and for the
> value we apply the template that looks like:
> FORMS/FORM/FIELDS/*[starts-with(name(), 'SCMCOMMENTS')], but doesn't have
> the FORMS/FORM/ in front and we keep adding them together with a blank at
> the end - if not the last one.
>
> 4) Then we do one set that concatenates the attributes of the FORM element
> together.
>
> 5) Lastly, we apply the attachment elements (which we don't have in this
> xml file) but does work fine in the finished one.
>
> This works fine with one set of comments, but is there a way to change the
> "FIELDS/*[not(starts-with(name(), 'SCMCOMMENTS'))]" to something that
> looks at multiple sets of comments. For example, if we had a file that
> looked something like:
>
> The sample xml file looks like:
> *********************************************************
> <?xml version="1.0" encoding="utf-8"?>
> <REPORT VERSION="1.10" FILENUM="" DESCRIPTION="Form Utility XML: 3/18/2008
> 12:27:13 PM" MAJORFORM="1004">
> <FORMS>
> <FORM NUM="1" FORMCODE="1004" SECCODE="1" DESC="" MAJOR="True" >
> <FIELDS>
> <OTHERFILENUMBER>692</OTHERFILENUMBER>
> <FNMA_FILENUMBER>693</FNMA_FILENUMBER>
> <SUBPROPADDRESS>3</SUBPROPADDRESS>
> <SCMCOMMENTS_1>This is a test line 1</SCMCOMMENTS_1>
> <SCMCOMMENTS_2>This is a test line 2</SCMCOMMENTS_2>
> <SCMCOMMENTS_3>This is a test line 3</SCMCOMMENTS_3>
> <SCMCOMMENTS_4>This is a test line 4</SCMCOMMENTS_4>
> <GEN_COMMENTS_1>Testing line 1</GEN_COMMENTS_1>
> <GEN_COMMENTS_2>Testing line 2</GEN_COMMENTS_2>
> <GEN_COMMENTS_3>Testing line 3</GEN_COMMENTS_3>
> <GEN_COMMENTS_4>Testing line 4</GEN_COMMENTS_4>
> <CMPHIST_TXT>The test line1</CMPHIST_TXT>
> <CMPHIST_TXT2 >The test line1</CMPHIST_TXT2>
> <CMPHIST_TXT3 >The test line1</CMPHIST_TXT3>
> <CMPHIST_TXT4 >The test line1</CMPHIST_TXT4>
> </FIELDS>
> </FORM>
> </FORMS>
> </REPORT>
> *********************************************************
>
> Could we change the select statements to something like:
>
> FIELDS/*[not(starts-with(name(), 'SCMCOMMENTS')) & not(starts-with(name(),
> 'GEN_COMMENTS')) & not(starts-with(name(), 'CMPHIST_TXT')) ]"
>
> and then set up different templates for each.
>
> Or do some type of contains that compares multiple strings?
>
I was able to put together a script that worked with the multiple groups of
comments that works pretty well. Not sure if the best way, especially since
I could have 20 or 30 groups of comments. But a start.
Here is the script I did:
************************************************
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="REPORT">
<xsl:copy>
<xsl:apply-templates
select="FORMS/FORM/FIELDS/*[not(starts-with(name(), 'SCMCOMMENTS')) and
not(starts-with(name(), 'GEN_COMMENTS')) and not(starts-with(name(),
'CMPHIST_TXT'))]"/>
<form>
<sectionNumber>0</sectionNumber>
<primary>True</primary>
<formName>
<xsl:value-of select="FORMS/FORM/@FORMCODE"/>
</formName>
<tagName>SCMCOMMENTS_1</tagName>
<flags>0</flags>
<format>0</format>
<value>
<xsl:apply-templates select="FORMS/FORM/FIELDS/*[starts-with(name(),
'SCMCOMMENTS')]"/>
</value>
</form>
<form>
<sectionNumber>0</sectionNumber>
<primary>True</primary>
<formName>
<xsl:value-of select="FORMS/FORM/@FORMCODE"/>
</formName>
<tagName>GEN_COMMENTS_1</tagName>
<flags>0</flags>
<format>0</format>
<value>
<xsl:apply-templates select="FORMS/FORM/FIELDS/*[starts-with(name(),
'GEN_COMMENTS')]"/>
</value>
</form>
<form>
<sectionNumber>0</sectionNumber>
<primary>True</primary>
<formName>
<xsl:value-of select="FORMS/FORM/@FORMCODE"/>
</formName>
<tagName>CMPHIST_TXT</tagName>
<flags>0</flags>
<format>0</format>
<value>
<xsl:apply-templates select="FORMS/FORM/FIELDS/*[starts-with(name(),
'CMPHIST_TXT')]"/>
</value>
</form>
<form>
<sectionNumber>
<xsl:value-of select="FORMS/FORM/@SECCODE"/>
</sectionNumber>
<primary>True</primary>
<formName>
<xsl:value-of select="FORMS/FORM/@FORMCODE"/>
</formName>
<tagName>FormFormats</tagName>
<flags>0</flags>
<format>0</format>
<value>
<xsl:apply-templates select="FORMS/FORM/@*"/>
</value>
</form>
<xsl:apply-templates select="FORMS/FORM/attachments/attachment"/>
</xsl:copy>
</xsl:template>
<xsl:template match="FIELDS/*[not(starts-with(name(), 'SCMCOMMENTS')) and
not(starts-with(name(), 'GEN_COMMENTS')) and not(starts-with(name(),
'CMPHIST_TXT'))]">
<form>
<sectionNumber>
<xsl:text>0</xsl:text>
</sectionNumber>
<primary>True</primary>
<formName>
<xsl:value-of select="../../@FORMCODE"/>
</formName>
<tagName>
<xsl:value-of select="name()"/>
</tagName>
<flags>0</flags>
<format>0</format>
<value>
<xsl:value-of select="."/>
</value>
</form>
</xsl:template>
<xsl:template match="FIELDS/*[starts-with(name(), 'SCMCOMMENTS')]">
<xsl:value-of select="."/>
<xsl:if test="position() != last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="FIELDS/*[starts-with(name(), 'GEN_COMMENTS')]">
<xsl:value-of select="."/>
<xsl:if test="position() != last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="FIELDS/*[starts-with(name(), 'CMPHIST_TXT')]">
<xsl:value-of select="."/>
<xsl:if test="position() != last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:template>
<xsl:template match="FORM/@*">
<xsl:value-of select="concat(name(), '=', .)"/>
<xsl:if test="position() != last()">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
************************************************
Thanks for all the help,
Tom
> Thanks,
>
> Tom
>> --
>>
>> Martin Honnen --- MVP XML
>> http://JavaScript.FAQTs.com/
>
>
| ||||||
| Company | Legal | Press | Partners | Careers | Sitemap | Contact Us | Altova Blog | Mobile | Full Site | |||
|
