Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Breaking XML into different nodes/sections

Posted on 2013-06-25
4
263 Views
Last Modified: 2013-06-26
Experts,

I have a XML and XSL I'm trying to format.  Currently its combining my "Detail" nodes together, so everywhere  it sees "Detail" it adds.  This is fine, but I want every detail I want it to spawn a new XML collection with the related tags under it like in target.xml I attached.  Any idea how I can have it break every detail section into its own collection while keeping header information in there?

Below is my XSLT:

<!-- Begin XST Style Sheet -->


<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://saxon.sf.net/" >

<!-- Indent in the output -->
<xsl:output indent="yes"/>

<!-- Match the root -->
<xsl:template match="ProcessImage">
<Import> <!-- Insert our Import Node -->
<Archive ConnectionID="1" Name="1"> <!-- Define our Application Connection String -->
<Document pass="True"> <!-- Statically set documents to pass -->
<xsl:for-each select="Pages/Page"> <!-- Ignore -->
<DocFile FileLoc="{@FileName}" /> <!-- Ignore -->
</xsl:for-each>
<Fields> <!-- Grab the field data and house it under the Fields Node -->
<xsl:for-each select="DataArea/Image/Header/*[not(self::Count)]"> <!-- Ignore Count if Present -->
<Field Name="{name(.)}" value="{./text()}" pass="True"/>
</xsl:for-each>
<xsl:for-each select="DataArea/Image/Detail/*[not(self::ImageData)]"> <!-- Ignore Image Data if Present -->
<Field Name="{name(.)}" value="{./text()}" pass="True"/>
</xsl:for-each>
</Fields>
</Document>
</Archive>
</Import>
</xsl:template>


</xsl:stylesheet>

Open in new window

target.xml
sample.xml
whatitsdoingnow.xml
0
Comment
Question by:lm1189
  • 3
4 Comments
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39275352
Something like this?

Note that it is now that breaking up the templates as I showed you before really helps keeping teh code readable

<!-- Begin XST Style Sheet -->


<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://saxon.sf.net/" >
  
  <!-- Indent in the output -->
  <xsl:output indent="yes"/>
  
  <!-- Match the root -->
  <xsl:template match="ProcessImage">
    <Import> <!-- Insert our Import Node -->
      <Archive ConnectionID="1" Name="1"> <!-- Define our Application Connection String -->
        <Document pass="True"> <!-- Statically set documents to pass -->
          <xsl:for-each select="Pages/Page"> <!-- Ignore -->
            <DocFile FileLoc="{@FileName}" /> <!-- Ignore -->
          </xsl:for-each>
          <xsl:apply-templates select="DataArea/Image/Header | DataArea/Image/Detail"/>
        </Document>
      </Archive>
    </Import>
  </xsl:template>
  
  <xsl:template match="Header">
    <DocFile FileLoc="{@FileName}" /> <!-- Ignore -->
    <Fields>
      <xsl:apply-templates select="*[not(self::Count)]"/> <!-- Ignore Count if Present -->
    </Fields>
  </xsl:template>
  
  <xsl:template match="Detail">
    <DocFile FileLoc="{@FileName}" /> <!-- Ignore -->
    <Fields>
      <xsl:apply-templates select="*[not(self::ImageData)]"/> <!-- Ignore Image Data if Present -->
    </Fields>
  </xsl:template>
  
  <xsl:template match="Header/* | Detail/*">
    <Field Name="{name()}" value="{.}" pass="True"/>
  </xsl:template>
  
  
</xsl:stylesheet>

Open in new window

0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 500 total points
ID: 39275372
However, it seems you want the Header repeated

<!-- Begin XST Style Sheet -->


<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://saxon.sf.net/" >
  
  <!-- Indent in the output -->
  <xsl:output indent="yes"/>
  
  <!-- Match the root -->
  <xsl:template match="ProcessImage">
    <Import> <!-- Insert our Import Node -->
      <Archive ConnectionID="1" Name="1"> <!-- Define our Application Connection String -->
        <Document pass="True"> <!-- Statically set documents to pass -->
          <xsl:for-each select="Pages/Page"> <!-- Ignore -->
            <DocFile FileLoc="{@FileName}" /> <!-- Ignore -->
          </xsl:for-each>
          <xsl:apply-templates select="DataArea/Image/Detail"/>
        </Document>
      </Archive>
    </Import>
  </xsl:template>
  
  <xsl:template match="Detail">
    <DocFile FileLoc="C:\SHARE FOLDER\SCANNED FILES\Scan{format-number(position() - 1, '0000')}.tif" /> <!-- Ignore -->
    <Fields>
      <xsl:apply-templates select="parent::Image/Header/*[not(self::Count)]"/> <!-- Ignore Count if Present -->
      <xsl:apply-templates select="*[not(self::ImageData)]"/> <!-- Ignore Image Data if Present -->
    </Fields>
  </xsl:template>
  
  <xsl:template match="Header/* | Detail/*">
    <Field Name="{name()}" value="{.}" pass="True"/>
  </xsl:template>
  
  
</xsl:stylesheet>

Open in new window

0
 

Author Comment

by:lm1189
ID: 39275721
Thank you!
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 39277210
welcome
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Getting lots of W3C errors in my XHTML site... 43 73
C# Delete from XML 10 48
C# Modify Read / Write / Update / Delete to  XML 2 75
XML Document XPath with Namespaces 3 27
The Problem How to write an Xquery that works like a SQL outer join, providing placeholders for absent data on the outer side?  I give a bit more background at the end. The situation expressed as relational data Let’s work through this.  I’ve …
Browsing the questions asked to the Experts of this forum, you will be amazed to see how many times people are headaching about monster regular expressions (regex) to select that specific part of some HTML or XML file they want to extract. The examp…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

860 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question