Loading ...
Sorry, an error occurred while loading the content.

Re: [XSL-FO] reading from external documents in XSLFO

Expand Messages
  • G. Ken Holman
    ... You are taking a programmer s approach to the problem, like many of my students try to do until they learn some principles of XSLT. ... Yes ... you do
    Message 1 of 8 , Apr 4, 2007
    • 0 Attachment
      At 2007-04-04 21:16 +0000, mina_hurray wrote:
      >I was not sure how to frame the subject and question for this porblem.
      >Basically, I am trying to read from an external XML file using
      >document() function.
      >My external file has:
      >...
      >I have an internal XML file which has:
      >...
      >Now I pass the paramter "name" thru the style sheet. Suppose I pass
      >"xyz" i want to check if the <prod> tag in the internal XML document
      >matches any of the<product> in the externak XML file. If it does I
      >want it to display "Hello world". How can I achieve this?
      >
      >The main issue is that <product> in the external file doesnot have a
      >wrapper around it, so when I store it in a variable and make a call to
      >it, it returs b0x chocolate pencil.

      You are taking a "programmer's approach" to the problem, like many of
      my students try to do until they learn some principles of XSLT.

      >Suppose I store this in a variable
      >test1, and store <company><prod> value in test2, I cannot compare each
      >value of test1 against test2, since test1 will have all three in this
      >fashion
      >
      >Box Chocolae pencil.

      Yes ... you do not need to use variables to accomplish what you need.

      >How can I match <company><prod> value to each single value in the
      >external xml?

      It is inherent in XSLT to be able to compare node sets. The
      comparison is initialized to false, and all of the nodes of one
      operand are compared to all of the nodes in the other operand. As
      soon as any comparison is true, the comparisons stop and true is
      returned. If you get false, then you know that there are no matches
      between the two node sets. You are not told *where* you get a true,
      you only get a true if *any* of the comparisons return true.

      So, using this principle, an example below shows that it is very easy
      in XSLT to get what I understand you to want.

      I hope this helps.

      . . . . . . . . . . . . Ken

      T:\ftemp>type mina0.xml
      <company>
      <name>xyz</name>
      <product>box</product>
      <product>chocolates</product>
      <product>pencil</product>
      </company>

      T:\ftemp>type mina1.xml
      <company>
      <prod>box</prod>
      </company>

      T:\ftemp>type mina2.xml
      <company>
      <prod>xyz</prod>
      </company>

      T:\ftemp>type mina.xsl
      <?xml version="1.0" encoding="US-ASCII"?>
      <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="1.0">

      <xsl:output method="text"/>

      <xsl:template match="/">
      <xsl:message>
      <xsl:choose>
      <xsl:when test="company/prod = document('mina0.xml')/company/product">
      The target document product is in the set of company products.
      </xsl:when>
      <xsl:otherwise>
      The target document product is not in the set of company products.
      </xsl:otherwise>
      </xsl:choose>
      </xsl:message>
      </xsl:template>

      </xsl:stylesheet>
      T:\ftemp>xslt mina1.xml mina.xsl con

      The target document product is in the set of company products.


      T:\ftemp>xslt mina2.xml mina.xsl con

      The target document product is not in the set of company products.


      T:\ftemp>

      --
      World-wide corporate, govt. & user group XML, XSL and UBL training
      RSS feeds: publicly-available developer resources and training
      G. Ken Holman mailto:gkholman@...
      Crane Softwrights Ltd. http://www.CraneSoftwrights.com/f/
      Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995)
      Male Cancer Awareness Aug'05 http://www.CraneSoftwrights.com/f/bc
      Legal business disclaimers: http://www.CraneSoftwrights.com/legal
    • W. Eliot Kimber
      ... Ken reminds me that this isn t actually good in either XSLT 1, because 1 string acts on the node in document order, while in 2 string doesn t allow a node
      Message 2 of 8 , Apr 4, 2007
      • 0 Attachment
        W. Eliot Kimber wrote:
        > In both XSLT 1 and 2 you should be able create a new document and then
        > examine it using normal select and match processing, but if you use
        > "value-of" then you'll just get it's string value.
        >
        > That is, something like:
        >
        > <xsl:if test="string(document($docuri)/company/prod) = 'box'">
        > <xsl:message>*** Found a box</xsl:message>
        > </xsl:if>

        Ken reminds me that this isn't actually good in either XSLT 1, because 1
        string acts on the node in document order, while in 2 string doesn't
        allow a node set (which is what the expression
        "document($docuri)/company/prod" returns), only a single node.

        Doh!

        Cheers,

        E.

        --
        W. Eliot Kimber
        Professional Services
        Innodata Isogen
        8500 N. Mopac, Suite 402
        Austin, TX 78759
        (214) 954-5198

        ekimber@...
        www.innodata-isogen.com
      • mina_hurray
        As usual this has helped me resolve my issue. This is part of a bigger issue that I have where I am filtering data. It is complicated and although I have a
        Message 3 of 8 , Apr 5, 2007
        • 0 Attachment
          As usual this has helped me resolve my issue. This is part of a bigger
          issue that I have where I am filtering data. It is complicated and
          although I have a working solution I wanted to know if there is a
          better approach to this problem.

          I have my input XML which has 5 levels <level1>...<level5> and level
          is the parent level for all these levels, while level2 is parent for
          level3, level 3 is parent of level4 and level 4 is parent of level5.
          Now I apply some conditions to filter out content at these levels.
          These levels are also formatted with number 1. So if I have some
          levels inbetween to be filtered out, I also want them to be numbered
          sequentially.

          sinple Example:

          <level1>
          <text>Some cond1 here </text>

          <level1>
          <level1>
          <text>Some cond2 here </text>

          <level1>
          <level1>
          <text>one more cond1 here </text>

          <level1>


          Expected output for 'cond1' is:

          1. Some cond1 here
          2. one more cond1 here

          Now, the way I am doing it in FO is using <xsl:number> and counting
          the levels where conditioning applies or does not.

          <xsl:number count="level[....whole set of filtering here...]"/>

          This is getting really cumbersome and I would like to know if there is
          any otehr way n XSLFO to approach this in a better optimised way.

          Thanks in advance

          --- In XSL-FO@yahoogroups.com, "G. Ken Holman" <gkholman@...> wrote:
          >
          > At 2007-04-04 21:16 +0000, mina_hurray wrote:
          > >I was not sure how to frame the subject and question for this porblem.
          > >Basically, I am trying to read from an external XML file using
          > >document() function.
          > >My external file has:
          > >...
          > >I have an internal XML file which has:
          > >...
          > >Now I pass the paramter "name" thru the style sheet. Suppose I pass
          > >"xyz" i want to check if the <prod> tag in the internal XML document
          > >matches any of the<product> in the externak XML file. If it does I
          > >want it to display "Hello world". How can I achieve this?
          > >
          > >The main issue is that <product> in the external file doesnot have a
          > >wrapper around it, so when I store it in a variable and make a call to
          > >it, it returs b0x chocolate pencil.
          >
          > You are taking a "programmer's approach" to the problem, like many of
          > my students try to do until they learn some principles of XSLT.
          >
          > >Suppose I store this in a variable
          > >test1, and store <company><prod> value in test2, I cannot compare each
          > >value of test1 against test2, since test1 will have all three in this
          > >fashion
          > >
          > >Box Chocolae pencil.
          >
          > Yes ... you do not need to use variables to accomplish what you need.
          >
          > >How can I match <company><prod> value to each single value in the
          > >external xml?
          >
          > It is inherent in XSLT to be able to compare node sets. The
          > comparison is initialized to false, and all of the nodes of one
          > operand are compared to all of the nodes in the other operand. As
          > soon as any comparison is true, the comparisons stop and true is
          > returned. If you get false, then you know that there are no matches
          > between the two node sets. You are not told *where* you get a true,
          > you only get a true if *any* of the comparisons return true.
          >
          > So, using this principle, an example below shows that it is very easy
          > in XSLT to get what I understand you to want.
          >
          > I hope this helps.
          >
          > . . . . . . . . . . . . Ken
          >
          > T:\ftemp>type mina0.xml
          > <company>
          > <name>xyz</name>
          > <product>box</product>
          > <product>chocolates</product>
          > <product>pencil</product>
          > </company>
          >
          > T:\ftemp>type mina1.xml
          > <company>
          > <prod>box</prod>
          > </company>
          >
          > T:\ftemp>type mina2.xml
          > <company>
          > <prod>xyz</prod>
          > </company>
          >
          > T:\ftemp>type mina.xsl
          > <?xml version="1.0" encoding="US-ASCII"?>
          > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          > version="1.0">
          >
          > <xsl:output method="text"/>
          >
          > <xsl:template match="/">
          > <xsl:message>
          > <xsl:choose>
          > <xsl:when test="company/prod =
          document('mina0.xml')/company/product">
          > The target document product is in the set of company products.
          > </xsl:when>
          > <xsl:otherwise>
          > The target document product is not in the set of company
          products.
          > </xsl:otherwise>
          > </xsl:choose>
          > </xsl:message>
          > </xsl:template>
          >
          > </xsl:stylesheet>
          > T:\ftemp>xslt mina1.xml mina.xsl con
          >
          > The target document product is in the set of company products.
          >
          >
          > T:\ftemp>xslt mina2.xml mina.xsl con
          >
          > The target document product is not in the set of company
          products.
          >
          >
          > T:\ftemp>
          >
          > --
          > World-wide corporate, govt. & user group XML, XSL and UBL training
          > RSS feeds: publicly-available developer resources and training
          > G. Ken Holman mailto:gkholman@...
          > Crane Softwrights Ltd. http://www.CraneSoftwrights.com/f/
          > Box 266, Kars, Ontario CANADA K0A-2E0 +1(613)489-0999 (F:-0995)
          > Male Cancer Awareness Aug'05 http://www.CraneSoftwrights.com/f/bc
          > Legal business disclaimers: http://www.CraneSoftwrights.com/legal
          >
        • G. Ken Holman
          ... Without knowing more of your input data and your conditions, I think I would have addressed this the same way with . But I wonder why you
          Message 4 of 8 , Apr 5, 2007
          • 0 Attachment
            At 2007-04-05 15:03 +0000, mina_hurray wrote:
            >As usual this has helped me resolve my issue. This is part of a bigger
            >issue that I have where I am filtering data. It is complicated and
            >although I have a working solution I wanted to know if there is a
            >better approach to this problem.
            >
            >I have my input XML which has 5 levels <level1>...<level5> and level
            >is the parent level for all these levels, while level2 is parent for
            >level3, level 3 is parent of level4 and level 4 is parent of level5.
            >Now I apply some conditions to filter out content at these levels.
            >These levels are also formatted with number 1. So if I have some
            >levels inbetween to be filtered out, I also want them to be numbered
            >sequentially.
            >
            >sinple Example:
            >
            ><level1>
            ><text>Some cond1 here </text>
            >
            ><level1>
            ><level1>
            ><text>Some cond2 here </text>
            >
            ><level1>
            ><level1>
            ><text>one more cond1 here </text>
            >
            ><level1>
            >
            >
            >Expected output for 'cond1' is:
            >
            >1. Some cond1 here
            >2. one more cond1 here
            >
            >Now, the way I am doing it in FO is using <xsl:number> and counting
            >the levels where conditioning applies or does not.
            >
            ><xsl:number count="level[....whole set of filtering here...]"/>
            >
            >This is getting really cumbersome and I would like to know if there is
            >any otehr way n XSLFO to approach this in a better optimised way.

            Without knowing more of your input data and your conditions, I think
            I would have addressed this the same way with <xsl:number>. But I
            wonder why you filter first and then count ... using level="any" you
            might be able to do the counting on the original data set.

            However, from your description, <xsl:number/> is appropriate because
            you are counting constructs in the source node tree. You could use
            XPath and the preceding:: and ancestor:: axis to replicate the
            counting ... or just the preceding-sibling:: axis if all of your
            constructs are siblings, but since that is built in to <xsl:number/>
            you are probably using the most appropriate construct.

            Yes, sometimes elaborate predicates are required to engage a number
            of different conditions simultaneously.

            I hope this helps.

            . . . . . . . . . . . Ken
            --
          • W. Eliot Kimber
            ... Depending on the complexity of what you re trying to do, it might be easier to implement or maintain either of these options: - Preprocess the input to do
            Message 5 of 8 , Apr 5, 2007
            • 0 Attachment
              G. Ken Holman wrote:

              > Yes, sometimes elaborate predicates are required to engage a number
              > of different conditions simultaneously.

              Depending on the complexity of what you're trying to do, it might be
              easier to implement or maintain either of these options:

              - Preprocess the input to do the filtering to an intermediate document
              and then apply the formatting rules to the intermediate result. This
              then separates the concerns of filtering from the concerns of formatting
              (this is what the DITA Open Toolkit does, for example). You can do this
              all in one style sheet or do it as two separate transforms in a pipeline.

              - Encapsulate the conditional check into one or more functions that both
              hide the details of the check and put the details into one place. This
              is easier in XSLT 2 where stylesheet-defined functions are part of the
              language, rather than an extension as they are in XSLT 1.

              Also, if your predicate statements are long and repeated, you can put
              them into an internal text entity like so:

              <!DOCTYPE xsl:stylesheet [
              <!ENTITY pred1 "this is a really long and gnarly predicate" >
              ]>
              <xsl:stylesheet>
              ...
              <xsl:template match="*[&pred1;]">
              ...
              </xsl:template>
              ...
              </xsl:template>

              Cheers,

              Eliot
              --
              W. Eliot Kimber
              Professional Services
              Innodata Isogen
              8500 N. Mopac, Suite 402
              Austin, TX 78759
              (214) 954-5198

              ekimber@...
              www.innodata-isogen.com
            • mina_hurray
              Thank you for your response. I did try using entity inside the style sheet. Somehow the style sheet is not picking up the entity name. Here is the structure:
              Message 6 of 8 , Apr 23, 2007
              • 0 Attachment
                Thank you for your response. I did try using entity inside the style
                sheet. Somehow the style sheet is not picking up the entity name.

                Here is the structure:

                <!DOCTYPE xsl:stylesheet [
                <!ENTITY Grp "document(...)/root/grp" >
                ]>

                The document() refereces an external xml file of the structure:

                <root>

                <grp>123</grp>

                </root>


                I reference this entity using &Grp; on the style sheet. But the style
                sheet is not recognizing it.

                Any suggestions will be greatly appreciated.

                --- In XSL-FO@yahoogroups.com, "W. Eliot Kimber" <ekimber@...> wrote:
                >
                > G. Ken Holman wrote:
                >
                > > Yes, sometimes elaborate predicates are required to engage a number
                > > of different conditions simultaneously.
                >
                > Depending on the complexity of what you're trying to do, it might be
                > easier to implement or maintain either of these options:
                >
                > - Preprocess the input to do the filtering to an intermediate document
                > and then apply the formatting rules to the intermediate result. This
                > then separates the concerns of filtering from the concerns of
                formatting
                > (this is what the DITA Open Toolkit does, for example). You can do this
                > all in one style sheet or do it as two separate transforms in a
                pipeline.
                >
                > - Encapsulate the conditional check into one or more functions that
                both
                > hide the details of the check and put the details into one place. This
                > is easier in XSLT 2 where stylesheet-defined functions are part of the
                > language, rather than an extension as they are in XSLT 1.
                >
                > Also, if your predicate statements are long and repeated, you can put
                > them into an internal text entity like so:
                >
                > <!DOCTYPE xsl:stylesheet [
                > <!ENTITY pred1 "this is a really long and gnarly predicate" >
                > ]>
                > <xsl:stylesheet>
                > ...
                > <xsl:template match="*[&pred1;]">
                > ...
                > </xsl:template>
                > ...
                > </xsl:template>
                >
                > Cheers,
                >
                > Eliot
                > --
                > W. Eliot Kimber
                > Professional Services
                > Innodata Isogen
                > 8500 N. Mopac, Suite 402
                > Austin, TX 78759
                > (214) 954-5198
                >
                > ekimber@...
                > www.innodata-isogen.com
                >
              Your message has been successfully submitted and would be delivered to recipients shortly.