XSLT цикл через элемент с attritbute против схемы - PullRequest
0 голосов
/ 19 сентября 2019

Привет, я довольно новичок в преобразованиях XML.У меня есть делика, где я пытаюсь перебрать элемент с атрибутом и дочерние элементы.Я работаю с существующим файлом, который ссылается на схему.Я пробовал несколько различных способов зацикливания, основываясь на том, что я мог почерпнуть из других комментариев, но все равно либо отбрасывал часть элемента, либо не появлялся на всех выборках ввода

    <PropertyDetail>
      <parkingType>Surface Lot</parkingType>
      <parkingSpaces>25</parkingSpaces>
      <parkingAssignmentAvailable>true</parkingAssignmentAvailable>
      <parkingAssignedFee>false</parkingAssignedFee>
      <parkingSpaceFee></parkingSpaceFee>
      <parkingComment>parking Comments</parkingComment>

      <parkingType>Garage Lot</parkingType>
      <parkingSpaces>12</parkingSpaces>
      <parkingAssignmentAvailable>true</parkingAssignmentAvailable>
      <parkingAssignedFee>true</parkingAssignedFee>
      <parkingSpaceFee>123.00</parkingSpaceFee>
      <parkingComment>parking Comments</parkingComment>

      <parkingType>Covered Lot</parkingType>
      <parkingSpaces>10</parkingSpaces>
      <parkingAssignmentAvailable>true</parkingAssignmentAvailable>
      <parkingAssignedFee>true</parkingAssignedFee>
      <parkingSpaceFee>75.00</parkingSpaceFee>
      <parkingComment>parking Comments</parkingComment>
   </propertyDetail>

Ожидаемый вывод

  <Information>
    <Parking ParkingType="Surface Lot">
        <Assigned>false</Assigned>
        <AssignedFee></AssignedFee>
        <SpaceFee></SpaceFee>
        <Spaces>25</Spaces>
         <Comment>parking Comments </Comment>
     </Parking>
     <Parking ParkingType="Garage Lot">
         <Assigned>true</Assigned>
         <AssignedFee>Paid</AssignedFee>
         <SpaceFee>123.00</SpaceFee>
         <Spaces>12</Spaces>
         <Comment>parking Comments </Comment>
      </Parking>
      <Parking ParkingType="Covered Lot">
          <Assigned>true</Assigned>
          <AssignedFee>Paid</AssignedFee>
          <SpaceFee>75.00</SpaceFee>
          <Spaces>10</Spaces>
          <Comment>parking Comments </Comment>
       </Parking>
   </Information>

Фрагмент таблицы стилей

<xsl:for-each select="propertyDetail/parkingType[position()&lt;5]">
            <Parking>

                                <xsl:attribute name="ParkingType">
                                    <xsl:variable name="parkingType" select="current()"/>
                                    <xsl:variable name="MITSParking">
                                        <xsl:value-of
                                            select="$parkingMap/types/type[databaseName=$parkingType]/mits30"
                                        />
                                    </xsl:variable>
                                    <xsl:choose>
                                        <xsl:when test="string-length($MITSParking) > 0">
                                            <xsl:value-of select="$MITSParking"/>
                                        </xsl:when>
                                        <xsl:otherwise>Other</xsl:otherwise>
                                    </xsl:choose>
                                </xsl:attribute>

                            <Assigned>
                                <xsl:choose>
                                    <xsl:when
                                        test="propertyDetail/parkingAssignmentAvailable = 'true'"
                                        >true</xsl:when>
                                    <xsl:when
                                        test="propertyDetail/parkingAssignmentAvailable = 'false'"
                                        >false</xsl:when>
                                    <xsl:otherwise>false</xsl:otherwise>
                                </xsl:choose>
                            </Assigned>
                            <AssignedFee>
                                <xsl:choose>
                                    <xsl:when test="propertyDetail/parkingAssignedFee = 'true'"
                                        >Paid</xsl:when>
                                    <xsl:when test="propertyDetail/parkingAssignedFee = 'false'"
                                        >Free</xsl:when>
                                </xsl:choose>
                            </AssignedFee>
                            <xsl:if test="string(number(propertyDetail/parkingSpaceFee)) != 'NaN' ">
                                <SpaceFee>
                                    <xsl:value-of select="propertyDetail/parkingSpaceFee"/>
                                </SpaceFee>
                            </xsl:if>
                            <xsl:if test="string(number(propertyDetail/parkingSpaces)) != 'NaN'">
                                <Spaces>
                                    <xsl:value-of select="propertyDetail/parkingSpaces"/>
                                </Spaces>
                            </xsl:if>
                            <xsl:if test="string-length(propertyDetail/parkingComment) > 0">
                                <Comment>
                                    <xsl:value-of select="propertyDetail/parkingComment"/>
                                </Comment>
                            </xsl:if>
                        </Parking>
        </xsl:for-each>

Схема

<xs:element name="Parking" minOccurs="0" maxOccurs="unbounded">
                          <xs:annotation>
                            <xs:documentation>Type</xs:documentation>
                          </xs:annotation>
                          <xs:complexType>
                            <xs:sequence>
                              <xs:element name="Assigned" type="xs:boolean" minOccurs="0"/>
                              <xs:element name="AssignedFee" minOccurs="0">
                                <xs:simpleType>
                                  <xs:restriction base="xs:string">
                                    <xs:enumeration value="Free"/>
                                    <xs:enumeration value="Paid"/>
                                    <xs:enumeration value="Both"/>
                                  </xs:restriction>
                                </xs:simpleType>
                              </xs:element>
                              <xs:element name="SpaceFee" type="xs:decimal" minOccurs="0"/>
                              <xs:element name="Spaces" type="xs:integer" minOccurs="0"/>
                              <xs:element name="Comment" minOccurs="0">
                                <xs:simpleType>
                                  <xs:restriction base="xs:string">
                                    <xs:maxLength value="500"/>
                                  </xs:restriction>
                                </xs:simpleType>
                              </xs:element>
                            </xs:sequence>
                            <xs:attribute name="ParkingType" use="required">
                              <xs:simpleType>
                                <xs:restriction base="xs:string">
                                  <xs:enumeration value="Surface Lot"/>
                                  <xs:enumeration value="Garage Lot"/>
                                  <xs:enumeration value="Covered Lot"/>
                                  <xs:enumeration value="Street"/>
                                  <xs:enumeration value="Other"/>
                                  <xs:enumeration value="None"/>
                                </xs:restriction>
                              </xs:simpleType>
                            </xs:attribute>
                          </xs:complexType>
                        </xs:element>

любая помощь будетс благодарностью

Добавление дополнительного кода для уточнения

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

    <xsl:include href="another xsl file"/>

    <xsl:template match="/">
        <PhysicalProperty xmlns:MITS="http://my-company.com/namespace"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="file:../supplied schema location">


            <xsl:for-each-group
                    select="/propertyList/property[CODE BLOCK}
                <Management>
                    <xsl:attribute name="IDType" >ManagementID</xsl:attribute>
                    <xsl:attribute name="IDRank" >primary</xsl:attribute>
                    <xsl:attribute name="IDValue"><xsl:value-of select="LSManagementCompanyId" /></xsl:attribute>
                    <PropertyContacts>
                        <Companies>
                            <Identification>
                                <xsl:attribute name="IDType">ManagementID</xsl:attribute>
                                <xsl:attribute name="IDRank">primary</xsl:attribute>
                                <xsl:attribute name="IDValue"><xsl:value-of select="LSManagementCompanyId" /></xsl:attribute>
                            </Identification>
                            <CompanyName>
                                <xsl:value-of select="substring(normalize-space(),1,50)"/>
                            </CompanyName>
                            <WebSite>
                                <xsl:value-of select="managementCompanyURL"/>
                            </WebSite>
                            <Logo>
                                <xsl:value-of select="managementCompanyLogo"/>
                            </Logo>
                        </Companies>
                    </PropertyContacts>
                </Management>
            </xsl:for-each-group>
            <xsl:for-each
                    select="/propertyList/property[CODE BLOCK]">
                <Property>
                    <xsl:attribute name="IDType"></xsl:attribute>
                    <xsl:attribute name="IDRank"></xsl:attribute>
                    <xsl:attribute name="IDValue"></xsl:attribute>
                    <PropertyID>
                        <Identification>                            
                            <xsl:attribute name="IDType"></xsl:attribute>
                            <xsl:attribute name="IDRank"></xsl:attribute>
                            <xsl:attribute name="IDValue"><xsl:value-of select=""/></xsl:attribute>
                        </Identification>
                        <Identification>
                            <xsl:attribute name="IDType"></xsl:attribute>
                            <xsl:attribute name="IDRank"></xsl:attribute>
                            <xsl:choose>
                                <xsl:when test="">
                                    <xsl:attribute name="IDValue"> <xsl:value-of select=""/></xsl:attribute>
                                </xsl:when>
                                <xsl:otherwise> <xsl:attribute name="IDValue">-1</xsl:attribute></xsl:otherwise>
                            </xsl:choose>
                        </Identification>
                        <Identification>
                            <xsl:attribute name="IDType" ></xsl:attribute>
                            <xsl:attribute name="IDRank" ></xsl:attribute>
                            <xsl:choose>
                                <xsl:when test="">
                                    <xsl:attribute name="IDValue"> <xsl:value-of select="" /></xsl:attribute>
                                </xsl:when>
                                <xsl:otherwise> <xsl:attribute name="IDValue">-1</xsl:attribute></xsl:otherwise>
                            </xsl:choose>                            
                        </Identification>
                        <MarketingName>
                            <xsl:value-of select=""/>
                        </MarketingName>
                        <StructureDescription>
                            <xsl:variable name="shortDescription">
                                <xsl:call-template name="remove-html">
                                    <xsl:with-param name="text">
                                        <xsl:value-of select="propertyDetail/shortDescription"/>
                                    </xsl:with-param>
                                </xsl:call-template>
                            </xsl:variable>
                            <xsl:call-template name="formatStringTruncate">
                                <xsl:with-param name="str"><xsl:value-of select="$shortDescription"/></xsl:with-param>
                                <xsl:with-param name="size"><xsl:value-of select="100"/></xsl:with-param>
                                <xsl:with-param name="delimiter"><xsl:value-of select="' '"/></xsl:with-param>
                            </xsl:call-template>
                        </StructureDescription>
                        <xsl:if test="string-length(WebSiteUrl) &lt;= 100">
                            <WebSite>
                                <xsl:value-of select="WebSiteUrl"/>
                            </WebSite>
                        </xsl:if>
                            <Address AddressType="">                            
                            [CODE BLOCK]
                        </Address>
                        <Phone PhoneType="office">
                            <PhoneNumber>
                                <xsl:variable name="phone">
                                    <xsl:choose>
                                        <xsl:when test="$Variable = 'true' and Property = 'true' and normalize-space(propertyContactPhoneList/phoneNumber[@Variable=$VariableId) = ''">
                                            <xsl:value-of
                                                    select="primaryPhone"
                                            />
                                        </xsl:when>
                                        <xsl:otherwise>
                                            <xsl:value-of
                                                    select="propertyPhoneList/phoneNumber[@Variable=$VariableId]"
                                            />
                                        </xsl:otherwise>
                                    </xsl:choose>
                                </xsl:variable>
                                <xsl:choose>
                                    <xsl:when test="string-length($phone) > 10">
                                        <xsl:value-of select="substring($phone, 1, 3)"/>
                                        <xsl:text>-</xsl:text>
                                        <xsl:value-of select="substring($phone, 4, 3)"/>
                                        <xsl:text>-</xsl:text>
                                        <xsl:value-of select="substring($phone, 7, 4)"/>
                                        <xsl:text>x</xsl:text>
                                        <xsl:value-of select="substring($phone, 11)"/>
                                    </xsl:when>
                                    <xsl:when test="string-length($phone) > 0">
                                        <xsl:value-of select="substring($phone, 1, 3)"/>
                                        <xsl:text>-</xsl:text>
                                        <xsl:value-of select="substring($phone, 4, 3)"/>
                                        <xsl:text>-</xsl:text>
                                        <xsl:value-of select="substring($phone, 7, 4)"/>
                                    </xsl:when>
                                </xsl:choose>
                            </PhoneNumber>
                        </Phone>
                        <Email>
                                <xsl:choose>
                                    <xsl:when test=" $VariableId = 'true' and Property = 'true' and normalize-space(propertyContactEmailList/mailLeadData[@Variable=$VariableId]/email) = ''">
                                        <xsl:value-of
                                                select="primaryContactEmail"
                                        />
                                    </xsl:when>
                                    <xsl:otherwise>
                                        <xsl:value-of
                                                select="propertyContactEmailList/mailLeadData[@Variable=$VariableId]/email"
                                        />
                                    </xsl:otherwise>
                                </xsl:choose>
                            </Email>
                    </PropertyID>
                    <xsl:variable name="VariableId">
                        <xsl:value-of select="propertyDetail/Type"/>
                    </xsl:variable>
                    <ILS_Identification RentalType="Market Rate">
                        <xsl:attribute name="ILS_IdentificationType">
                            <xsl:variable name="IlsIdentificationType">
                                <xsl:value-of
                                        select="$structureMap/=$VariableId]/mits41/ILS_IdentificationType"
                                />
                            </xsl:variable>
                            <xsl:choose>
                                <xsl:when test="string-length($VariableType) > 0">
                                    <xsl:value-of select="$VariableType"/>
                                </xsl:when>
                                <xsl:otherwise>Unspecified</xsl:otherwise>
                            </xsl:choose>
                        </xsl:attribute>
                        <Latitude>
                            <xsl:value-of select="propertyAddress"/>
                        </Latitude>
                        <Longitude>
                            <xsl:value-of select="propertyAddress"/>
                        </Longitude>
                    </ILS_Identification>

                    <Information>

                        <Type>
                            <xsl:variable name="Type">
                                <xsl:value-of
                                        select="$Map//mits41/Type"
                                />
                            </xsl:variable>
                            <xsl:choose>
                                <xsl:when test="string-length($Type) > 0">
                                    <xsl:value-of select="$Type"/>
                                </xsl:when>
                                <xsl:otherwise>Unspecified</xsl:otherwise>
                            </xsl:choose>

                        </Type>
                        <UnitCount>
                            <xsl:value-of select="propertyDetail/unitCount"/>
                        </UnitCount>
                        <xsl:if test="string-length(propertyDetail/yearBuilt) > 0">
                            <YearBuilt>
                                <xsl:value-of select="propertyDetail/yearBuilt"/>
                            </YearBuilt>
                        </xsl:if>
                        <xsl:if test="string-length(propertyDetail/yearRemodeled) > 0">
                            <YearRemodeled>
                                <xsl:value-of select="propertyDetail/yearRemodeled"/>
                            </YearRemodeled>
                        </xsl:if>
                        <xsl:for-each select="officeHours/day">
                            <xsl:sort select="@day" order="ascending" data-type="number"/>
                            <xsl:if test="string-length(sT)> 0 or string-length(eT) > 0">
                                <xsl:call-template name="formatOfficeHours">
                                    <xsl:with-param name="sT" select="sT1"/>
                                    <xsl:with-param name="eT" select="eT1"/>
                                    <xsl:with-param name="dow" select="@dayOfWeek"/>
                                </xsl:call-template>
                            </xsl:if>
                            <xsl:if test="string-length(sT2)> 0 or string-length(eT2) > 0">
                                <xsl:call-template name="formatOfficeHours">
                                    <xsl:with-param name="sT" select="sT2"/>
                                    <xsl:with-param name="eT" select="eT2"/>
                                    <xsl:with-param name="dow" select="@dayOfWeek"/>
                                </xsl:call-template>
                            </xsl:if>
                        </xsl:for-each>
                        <ShortDescription>
                            <xsl:variable name="shortDescription">
                                <xsl:call-template name="remove-html">
                                    <xsl:with-param name="text">
                                        <xsl:value-of select="propertyDetail/shortDescription"/>
                                    </xsl:with-param>
                               </xsl:call-template>
                            </xsl:variable>
                            <xsl:call-template name="formatStringTruncate">
                                <xsl:with-param name="str"><xsl:value-of select="$shortDescription"/></xsl:with-param>
                                <xsl:with-param name="size"><xsl:value-of select="500"/></xsl:with-param>
                                <xsl:with-param name="delimiter"><xsl:value-of select="' '"/></xsl:with-param>
                            </xsl:call-template>
                        </ShortDescription>
                        <LongDescription>
                            <xsl:variable name="fullDescription">
                                <xsl:call-template name="remove-html">
                                    <xsl:with-param name="text">
                                        <xsl:value-of select="propertyDetail/fullDescription"/>
                                    </xsl:with-param>
                                </xsl:call-template>
                            </xsl:variable>
                            <xsl:call-template name="formatStringTruncate">
                                <xsl:with-param name="str"><xsl:value-of select="$fullDescription"/></xsl:with-param>
                                <xsl:with-param name="size"><xsl:value-of select="1000"/></xsl:with-param>
                                <xsl:with-param name="delimiter"><xsl:value-of select="' '"/></xsl:with-param>
                            </xsl:call-template>
                        </LongDescription>
                        <xsl:variable name="numberLeaseTerms">
                            <xsl:value-of select="count(propertyDetail/length/leaseTerm)"/>
                        </xsl:variable>
                        <xsl:variable name="validLeaseTerms">
                            <xsl:value-of select="count(propertyDetail/lleangth/lTerm[()])"/>
                        </xsl:variable>
                        <length>
                            <xsl:choose>
                                <xsl:when test="$validLeaseTerms>0">
                                    <xsl:for-each select="propertyDetail/length/leaseTerm[(.=$Map/mits20/length)]">
                                        <xsl:value-of select="."/>
                                        <xsl:if test="position() != last()">
                                            <xsl:text>,</xsl:text>
                                        </xsl:if>
                                    </xsl:for-each>
                                </xsl:when>
                                <xsl:when test="$numberLeaseTerms=1 and propertyDetail/length/leaseTerm='None'">None</xsl:when>
                                <xsl:otherwise>Variable</xsl:otherwise>
                            </xsl:choose>
                        </length>
                        <Parking>
                            <xsl:for-each select="propertyDetail/parkingType">
                                <xsl:attribute name="ParkingType">
                                    <xsl:variable name="parkingType" select="current()"/>
                                    <xsl:variable name="MITSParking">
                                        <xsl:value-of
                                                select="$parkingMap/types/type[databaseName=$parkingType]/mits41"
                                        />
                                    </xsl:variable>
                                    <xsl:choose>
                                        <xsl:when test="string-length($MITSParking) > 0">
                                            <xsl:value-of select="$MITSParking"/>
                                        </xsl:when>
                                        <xsl:otherwise>Other</xsl:otherwise>
                                    </xsl:choose>
                                </xsl:attribute>
                            </xsl:for-each>
                            <Assigned>
                                <xsl:choose>
                                    <xsl:when
                                            test="propertyDetail/parkingAssignmentAvailable = 'true'"
                                    >true</xsl:when>
                                    <xsl:when
                                            test="propertyDetail/parkingAssignmentAvailable = 'false'"
                                    >false</xsl:when>
                                    <xsl:otherwise>false</xsl:otherwise>
                                </xsl:choose>
                            </Assigned>
                            <AssignedFee>
                                <xsl:choose>
                                    <xsl:when test="propertyDetail/parkingAssignedFee = 'true'"
                                    >Paid</xsl:when>
                                    <xsl:when test="propertyDetail/parkingAssignedFee = 'false'"
                                    >Free</xsl:when>
                                </xsl:choose>
                            </AssignedFee>
                            <xsl:if test="string(number(propertyDetail/parkingSpaceFee)) != 'NaN' ">
                                <SpaceFee>
                                    <xsl:value-of select="propertyDetail/parkingSpaceFee"/>
                                </SpaceFee>
                            </xsl:if>
                            <xsl:if test="string(number(propertyDetail/parkingSpaces)) != 'NaN'">
                                <Spaces>
                                    <xsl:value-of select="propertyDetail/parkingSpaces"/>
                                </Spaces>
                            </xsl:if>
                            <xsl:if test="string-length(propertyDetail/parkingComment) > 0">
                                <Comment>
                                    <xsl:value-of select="propertyDetail/parkingComment"/>
                                </Comment>
                            </xsl:if>
                        </Parking>

                    </Information>

                </Property>
            </xsl:for-each>
        </PhysicalProperty>
    </xsl:template>
</xsl:stylesheet>

1 Ответ

1 голос
/ 19 сентября 2019

AFAICT, вы хотите сделать:

XSLT 2.0

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

<xsl:template match="/propertyDetail">
    <Information>
        <xsl:for-each-group select="*" group-starting-with="parkingType">
            <Parking ParkingType="{.}">
                <xsl:apply-templates select="current-group() except ."/>
            </Parking>
        </xsl:for-each-group>
    </Information>
</xsl:template>

<xsl:template match="parkingAssignmentAvailable">
    <Assigned>
        <xsl:value-of select="."/>
    </Assigned>
</xsl:template>

<xsl:template match="parkingAssignedFee">
    <AssignedFee>
        <xsl:choose>
            <xsl:when test=".='true'">Paid</xsl:when>
            <xsl:when test=".='false'">Free</xsl:when>
        </xsl:choose>               
    </AssignedFee>
</xsl:template>

<xsl:template match="parkingSpaceFee">
    <SpaceFee>
        <xsl:value-of select="."/>
    </SpaceFee>
</xsl:template>

<xsl:template match="parkingSpaces">
    <Spaces>
        <xsl:value-of select="."/>
    </Spaces>
</xsl:template>

<xsl:template match="parkingComment">
    <Comment>
        <xsl:value-of select="."/>
    </Comment>
</xsl:template>

</xsl:stylesheet>

Демо (с исправленным вводом): https://xsltfiddle.liberty -development.net / pPJ8LUX / 2

...