Read XML file inside XSLT and using that to constr

2019-06-09 20:44发布

问题:

I want to read an XML file inside XSLT and check its nodes. if they match the value of XML node to which I am applying the transform, then grab the value of the XML node and use it to construct a new XML structure.

Here is an example to illustrate my problem. I think many people can use this question for reference to achieve similar functionality.

Referenced.xml

<xml>
  <root>
    <Id id = "1">
      <fields>
        <field>
          <name> Name1 </name>
          <value> Val1 </value>
        </field>
        <field>
          <name> Name2 </name>
          <value> Val2 </value>
        </field>
      </fields> 
    </Id>
    <Id id = "2">
    ...
    </Id>
  </root>
</xml>

Xml.xml

<XML>
  <Fields>
   <Id id = "1">
    <F1> Value1 </F1>
    <F2> Value2 </F2>
    <F1> Value3 </F1>
    <F4> Value4 </F4>
 </Id>
  </Fields>
</XML>

Now, I want to create a transform which will iterate through the XML file (Referenced.xml) and check where Id inside the both xml's match and then, inside that id, Name1 = F1 and wherever it is then, fetch 'value' for that 'name' and create an XML structure like

<outputXml>
  <Field id="Val1">
    <val> Value1 </val>
  </Field>
  <Field id="Val2">
    <val> Value2 </val>
  </Field> ... and so on
</outputXml>

I know I have to use document(), but I am not sure how do you iterate through the Referenced.xml inside xsl and use if, else to achieve the functionality needed ?

回答1:

Check this one:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:param name="file1" select="document('Referenced.xml')"/>
  <xsl:param name="file2" select="document('Xml.xml')"/>

  <xsl:output method="xml" encoding="UTF-8" indent="yes"/>

  <xsl:template match="/">
    <outputXml>
      <xsl:for-each select="$file1//Id">
        <xsl:variable name="ReferencedID" select="@id"/>
        <xsl:choose>
          <xsl:when test="$ReferencedID = $file2//Id/@id">
            <xsl:for-each select="fields/field">
              <Field id="{normalize-space(value)}"><xsl:value-of select="value"/></Field>
            </xsl:for-each>
          </xsl:when>
        </xsl:choose>
      </xsl:for-each>
    </outputXml>
  </xsl:template>

</xsl:stylesheet>

to get output:

<outputXml>
   <Field id=" Val1 "> Val1 </Field>
   <Field id=" Val2 "> Val2 </Field>
</outputXml>


回答2:

Here's a piece of working code:

<!-- loads a file like resources/strings-en.xml into a variable document-->
<xsl:variable 
    name="messages" 
    select="document(concat('resources/strings-', $lang, '.xml'))/my:strings"
/>

...

<!-- uses the loaded document for selecting -->
<xsl:template name="localized-string">
    <xsl:param name="name"/>
    <xsl:value-of select="$messages/my:string[@name=$name]"/>
</xsl:template>

As you may see, once you have read a document into a variable, it looks like a normal document, you apply XPath expressions to traverse it, etc.



回答3:

Try this Your XML FILE Chapters.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="ditaXSL.xsl"?>
<map>
    <title>Syncro phone user guide</title>
    <topicref href="gettingStarted.dita"/>
</map>

your XSl name : ditaXSL.xsl

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:f="Functions"
    version="2.0">
    <xsl:template match="map">
        <html>
            <title>
                <xsl:value-of select="title" />
            </title>
            <h4>
                <xsl:value-of select="title" />
            </h4>

            <body>
                <table>
                    <tr>
                        <th>TOPIC REF</th>
                    </tr>

                    <xsl:for-each select="topicref">
                        <tr>
                            <td>
                                <xsl:apply-templates select="document(@href)/topic" />
                            </td>
                        </tr>
                    </xsl:for-each>
                </table>
            </body>

        </html>
    </xsl:template>

    <xsl:template match="topic">
        <xsl:apply-templates />
    </xsl:template>


    <xsl:template match="title">
        Chapter :
        <h6>
            <xsl:value-of select="." />
        </h6>
    </xsl:template>

    <xsl:template match="body">
        Description :
        <h5>
            <xsl:value-of select="." />
        </h5>
    </xsl:template>
</xsl:stylesheet>

Example gettingStarted.dita file mentioned in xml file.

<?xml version="1.0" encoding="UTF-8"?>
<topic>
  <title>Getting started</title>
  <body>This is introduction</body>
</topic>


标签: xml xslt