2016-08-25 3 views
0

Рассмотрим следующий входной XML:XSLT Создание вложенных элементов при существующем контексте при соблюдении пространств имен

<b:PropertyInfo id="N91" xmlns:b="http://www.ACORD.org/standards/PC_Surety/ACORD1/xml/"> 
    <b:CommlPropertyInfo id="N92" LocationRef="LOCATION1"> 
     <b:SubjectInsuranceCd id="SubjectInsuranceCd-1">BLDG</b:SubjectInsuranceCd> 
     <b:CommlCoverage id="N95"> 
      <b:CoverageCd id="N96">BLDG</b:CoverageCd> 
      <b:Limit id="N97"> 
       <b:FormatInteger id="N98">250000</b:FormatInteger> 
       <b:ValuationCd id="N99">RC</b:ValuationCd> 
      </b:Limit> 
     </b:CommlCoverage> 
     <b:CommlCoverage id="N100"> 
      <b:CoverageCd id="N101">INFL</b:CoverageCd> 
      <b:Limit id="N102"> 
       <b:FormatPct id="N103">100</b:FormatPct> 
      </b:Limit> 
     </b:CommlCoverage> 
    </b:CommlPropertyInfo> 
</b:PropertyInfo 

Если желаемый результат:

<b:PropertyInfo id="N91" xmlns:b="http://www.ACORD.org/standards/PC_Surety/ACORD1/xml/"> 
    <b:CommlPropertyInfo id="N92" LocationRef="LOCATION1"> 
     <b:SubjectInsuranceCd id="SubjectInsuranceCd-1">BLDG</b:SubjectInsuranceCd> 
     <b:CommlCoverage id="N95"> 
      <b:CoverageCd id="N96">BLDG</b:CoverageCd> 
      <b:Limit id="N97"> 
       <b:FormatInteger id="N98">250000</b:FormatInteger> 
       <b:ValuationCd id="N99">RC</b:ValuationCd> 
      </b:Limit> 
      <CommlCoverageSupplement xmlns="http://www.ACORD.org/standards/PC_Surety/ACORD1/xml/"> 
       <CoverageSubCd>INFL</CoverageSubCd> 
       <AnnualIncrease>100</AnnualIncrease> 
      </CommlCoverageSupplement> 
     </b:CommlCoverage> 
     <b:CommlCoverage id="N100"> 
      <b:CoverageCd id="N101">INFL</b:CoverageCd> 
      <b:Limit id="N102"> 
       <b:FormatPct id="N103">100</b:FormatPct> 
      </b:Limit> 
     </b:CommlCoverage> 
    </b:CommlPropertyInfo> 
</b:PropertyInfo> 

У меня есть XSLT, что делает почти то, что я хочу :

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.ACORD.org/standards/PC_Surety/ACORD1/xml/" > 
    <xsl:strip-space elements="*" /> 

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

    <xsl:template match="PropertyInfo/CommlPropertyInfo/CommlCoverage[CoverageCd='BLDG']"> 
     <xsl:variable name="increase"> 
      <xsl:value-of select="../CommlCoverage[CoverageCd='INFL']/Limit/FormatPct" /> 
     </xsl:variable> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*" /> 
      <CommlCoverageSupplement> 
       <CoverageSubCd>INFL</CoverageSubCd> 
       <AnnualIncrease> 
        <xsl:value-of select="$increase" /> 
       </AnnualIncrease> 
      </CommlCoverageSupplement> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Моя забота об этом преобразовании заключается в использовании исходных текстовых элементов для создания новых элементов ts - которые не будут иметь правильные пространства имен и, следовательно, созданный им xml неверен. Из моего чтения, я понимаю, что это «плохая практика» для использования исходного текста для создания элементов xml. Мое понимание использования исходного текста таким образом должно использоваться, когда вы преобразуете xml в другой формат, например html.

Для этого я попытался использовать <xsl:element>, но я использую его неправильно. Как я это написал, процессор XSLT позволяет мне знать, что это неверный формат, чтобы иметь <xsl:element> вложен в другой:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xpath-default-namespace="http://www.ACORD.org/standards/PC_Surety/ACORD1/xml/"> 
    <xsl:strip-space elements="*" /> 

    <!-- element template that copies over elements --> 
    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()" /> 
     </xsl:copy> 
    </xsl:template> 

    <!-- "other" template to copy the rest of the nodes --> 
    <xsl:template match="comment() | processing-instruction()"> 
     <xsl:copy /> 
    </xsl:template> 

    <xsl:template 
     match="PropertyInfo/CommlPropertyInfo/CommlCoverage[CoverageCd='BLDG']"> 
     <xsl:variable name="increase"> 
      <xsl:value-of select="../CommlCoverage[CoverageCd='INFL']/Limit/FormatPct" /> 
     </xsl:variable> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*" /> 
      <xsl:element name="CommlCoverageSupplement" namespace="{namespace-uri()}"> 
       <xsl:element name="CoverageSubCd" namespace="{namespace-uri()}">INFL</xsl:element> 
       <xsl:element name="AnnualIncrease" namespace="{namespace-uri()}"> 
        <xsl:value-of select="$increase" /> 
       </xsl:element> 
      </xsl:element> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Как правильно XSLT способ создать новые вложенные элементы, как это в то время все еще уважая пространство имен?

EDIT: Оказывается, это была только ошибка редактора. Вы действительно можете создать вложенную XSL: элементы элемента, и ответ на самом деле в этом вопросе повторно отправленный здесь для ясности:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xpath-default-namespace="http://www.ACORD.org/standards/PC_Surety/ACORD1/xml/"> 
    <xsl:strip-space elements="*" /> 

    <!-- element template that copies over elements --> 
    <xsl:template match="@* | node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()" /> 
     </xsl:copy> 
    </xsl:template> 

    <!-- "other" template to copy the rest of the nodes --> 
    <xsl:template match="comment() | processing-instruction()"> 
     <xsl:copy /> 
    </xsl:template> 

    <xsl:template 
     match="PropertyInfo/CommlPropertyInfo/CommlCoverage[CoverageCd='BLDG']"> 
     <xsl:variable name="increase"> 
      <xsl:value-of select="../CommlCoverage[CoverageCd='INFL']/Limit/FormatPct" /> 
     </xsl:variable> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*" /> 
      <xsl:element name="CommlCoverageSupplement" namespace="{namespace-uri()}"> 
       <xsl:element name="CoverageSubCd" namespace="{namespace-uri()}">INFL</xsl:element> 
       <xsl:element name="AnnualIncrease" namespace="{namespace-uri()}"> 
        <xsl:value-of select="$increase" /> 
       </xsl:element> 
      </xsl:element> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

«* У меня есть xslt, который делает почти то, что я хочу * «Что такое ** точный результат **, который вы хотите получить? –

+0

Обновлено, чтобы включить образец xml желаемого результата. Я должен отметить, что любой семантический эквивалент пространства имен (с префиксами или что-то еще) также является приемлемым. Все, где предоставлена ​​структура, созданная при принадлежности к пространству имен по умолчанию, указанному xslt. – Russ

+0

Вывод, который вы показываете, не является корректным XML, потому что префикс 'b:' не связан с пространством имен. У вашего входа есть тот же недостаток. –

ответ

0

Я beileve, что если добавить следующее объявление пространства имен:

xmlns:b="http://www.ACORD.org/standards/PC_Surety/ACORD1/xml/" 

в xsl:stylesheet элемента, и добавить префикс b: к буквенным элементам результата:

<b:CommlCoverageSupplement> 
     <b:CoverageSubCd>INFL</b:CoverageSubCd> 
     <b:AnnualIncrease> 
      <xsl:value-of select="$increase" /> 
     </b:AnnualIncrease> 
    </b:CommlCoverageSupplement> 

вы получите результат, который вы необходимо.


Если - по какой-то странной причине - вы не хотите, добавленные элементы имеют префикс b: (но по-прежнему находиться в том же пространстве имен), вы могли бы сделать просто:

 <CommlCoverageSupplement xmlns="http://www.ACORD.org/standards/PC_Surety/ACORD1/xml/"> 
     <CoverageSubCd>INFL</CoverageSubCd> 
     <AnnualIncrease> 
      <xsl:value-of select="$increase" /> 
     </AnnualIncrease> 
    </CommlCoverageSupplement>