XSLT assistance - repeating data

2019-07-28 09:42发布

问题:

I have an issue where there is no useful tags associated with some data, the data is included at the head of the document, but I can not get this to look how I want.

I've had the Column1 text replacing the tags, but as they are all labelled , it doesn't help much. I'm slowly learning how XSLTs work, but this is beyond my knowledge.

Any assistance would be appreciated.

Input data

<results>
<header>
    <a>Column 1 Customer Name</a>
    <a>Column 2 Customer Add</a>
    <a>Column3</a>
    <a>Column4</a>
</header>
<body>
    <line>
        <a>Data1</a>
        <a>Data2</a>
        <a>Data3</a>
        <a>Data4</a>
    </line>
    <line>
        <a>Data1</a>
        <a>Data2</a>
        <a>Data3</a>
        <a>Data4</a>
    </line>
</body>
</results>

>

Required XML

 <?xml version="1.0"?>
<results>
<header>
    <a>Column 1 Customer Name</a>
    <a>Column 2 Customer Add</a>
    <a>Column3</a>
    <a>Column4</a>
</header>
<body>
    <line>
        <Column1CustomerName>Data1</Column1CustomerName>
        <Column2CustomerAdd>Data2</Column2CustomerAdd>
        <Column3>Data3</Column3>
        <Column4>Data4</Column4>
    </line>
    <line>
        <Column1CustomerName>Data1</Column1CustomerName>
        <Column2CustomerAdd>Data2</Column2CustomerAdd>
        <Column3>Data3</Column3>
        <Column4>Data4</Column4>
    </line>
</body>
</results>

Following on from a users response, I have implemented the following XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>

<xsl:template match="/results">
<results>
<xsl:copy-of select="header"/>
<body>
  <xsl:for-each select="body/line">
    <line>
      <xsl:for-each select="a">
        <xsl:variable name="index" select="position()" />
        <xsl:element name="{//header/a[$index]}">
          <xsl:value-of select="." />
        </xsl:element>
      </xsl:for-each>
    </line>
  </xsl:for-each>
 </body>
 </results>
</xsl:template>
</xsl:stylesheet>

My problem now is if a header contains a space, as this causes the style sheet to try and create an XML tag with a space in.

I've tried using the replace function, which has been suggested.

<xsl:element name="{replace(//cols/c[$index],' ','')}">

And I seem to be getting this wrong, or calling this in the wrong place.

Thanks for everyone's input.

回答1:

You need <xsl:element> to do the trick.

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>

<xsl:template match="/results">
  <results>
    <xsl:copy-of select="header"/>
    <body>
      <xsl:for-each select="body/line">
        <line>
          <xsl:for-each select="a">
            <xsl:variable name="index" select="position()" />
            <xsl:element name="{replace(//header/a[$index], ' ', '')}">
              <xsl:value-of select="." />
            </xsl:element>
          </xsl:for-each>
        </line>
      </xsl:for-each>
    </body>
  </results>
</xsl:template>
</xsl:stylesheet>


回答2:

Here's a completely "push-oriented" (focuses on usage of <xsl:template> and <xsl:apply-templates>, doesn't explicitly pull data with elements such as <xsl:value-of>, etc.) solution that doesn't use <xsl:for-each>.

When this XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output omit-xml-declaration="no" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="@*|node()">
     <xsl:copy>
       <xsl:apply-templates select="@*|node()" />
     </xsl:copy>
  </xsl:template>

  <xsl:template match="line/a">
    <xsl:variable name="vPos" select="position()" />
    <xsl:element name="{/*/header/a[$vPos]}">
      <xsl:apply-templates />
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

...is applied to the provided XML:

<results>
  <header>
    <a>Column1</a>
    <a>Column2</a>
    <a>Column3</a>
    <a>Column4</a>
  </header>
  <body>
    <line>
      <a>Data1</a>
      <a>Data2</a>
      <a>Data3</a>
      <a>Data4</a>
    </line>
    <line>
      <a>Data1</a>
      <a>Data2</a>
      <a>Data3</a>
      <a>Data4</a>
    </line>
  </body>
</results>

...the wanted answer is produced:

<?xml version="1.0"?>
<results>
  <header>
    <a>Column1</a>
    <a>Column2</a>
    <a>Column3</a>
    <a>Column4</a>
  </header>
  <body>
    <line>
      <Column1>Data1</Column1>
      <Column2>Data2</Column2>
      <Column3>Data3</Column3>
      <Column4>Data4</Column4>
    </line>
    <line>
      <Column1>Data1</Column1>
      <Column2>Data2</Column2>
      <Column3>Data3</Column3>
      <Column4>Data4</Column4>
    </line>
  </body>
</results>


标签: xml xslt repeat