Скопируйте атрибуты в XSLT - PullRequest
0 голосов
/ 21 июля 2010

Теперь у меня есть XML-файл, как показано ниже:

<DM Name="A DM"> 
  <DV  id="SQL:Select something from db" Name="DV 1"> 
    <Sample aid="SQL:Select something from db" /> 
  </DV> 
  <DV  id="SQL:Select something from db" Name="DV 2"> 
    <Sample aid="SQL:Select something from db" name ="DC"> 
      good 
    </Sample> 
  </DV> 
</DM> 

Я хочу использовать XSLT для преобразования, в этом примере есть параметр, который определяет, какой DV следует преобразовать: если параметр ($ dvIndex = 0), то просто сохраните все элементы и атрибуты, просто преобразуйте приписать атрибуты со значением, начинающимся с «SQL:», если ($ dvindext> 0), просто преобразовать определенный DV (удалить другой DV). Теперь я пишу XSLT, как показано ниже, но он пропускает атрибуты DM, я не знаю, как копировать атрибуты DM. Я не знаю, есть ли лучшее решение. XML-файл:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
    xmlns:user="urn:my-scripts"
>
  <xsl:output method="xml" indent="yes"/>
  <msxsl:script language="C#" implements-prefix="user">
    <![CDATA[
     public string UpperCase(string value){
      return value.ToUpper();
     }
      ]]>
  </msxsl:script>

  <xsl:param name="dvIndex" select="2" />

  <xsl:template match="DM" >
    <xsl:copy>
      <xsl:choose>
        <xsl:when test="$dvIndex > 0">
          <xsl:apply-templates select="DV[$dvIndex]"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
          </xsl:copy>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:copy>
  </xsl:template>

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

  <!--[starts-with(translate(substring(.,1,4),'SQL:','sql:'),'sql:')]-->
  <xsl:template match="@*[user:UpperCase(substring(.,1,4))='SQL:']">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="'parsedSQL'"/>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

этот вопрос также связан с моим вопросом 2 # ( Как преобразовать только атрибут XML-файла с помощью XSLT и оставить другой контент? )

Большое спасибо!

Ответы [ 2 ]

1 голос
/ 21 июля 2010

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="dvIndex" select="2" />
    <xsl:template match="DM" >
        <xsl:copy>
            <xsl:apply-templates select="@*|DV[$dvIndex]"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*[starts-with(translate(substring(.,1,4),'SQL:','sql:'),'sql:')]">
        <xsl:attribute name="{name()}">
            <xsl:value-of select="'parsedSQL'"/>
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

Результат:

<DM Name="A DM">
<DV id="parsedSQL" Name="DV 2">
<Sample aid="parsedSQL" name="DC">
      good
    </Sample>
</DV>
</DM>

С параметром dvIndex в 0:

<DM Name="A DM"></DM>

Примечание : Избегайте сценариев: это не стандартное решение, оно заставляет загружать механизм сценариев при каждом использовании.

РЕДАКТИРОВАТЬ : Если вы хотите обрабатывать каждый DV, когда $ dvIndex равен 0, тогда эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="dvIndex" select="2" />
    <xsl:template match="DM" >
        <xsl:copy>
            <xsl:apply-templates select="@*|DV[$dvIndex]|DV[not($dvIndex)]"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*[starts-with(translate(substring(.,1,4),'SQL:','sql:'),'sql:')]">
        <xsl:attribute name="{name()}">
            <xsl:value-of select="'parsedSQL'"/>
        </xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

Если $ dvIndex равно 0, выведите:

<DM Name="A DM">
<DV id="parsedSQL" Name="DV 1">
<Sample aid="parsedSQL"></Sample>
</DV>
<DV id="parsedSQL" Name="DV 2">
<Sample aid="parsedSQL" name="DC">
      good
    </Sample>
</DV>
</DM>
0 голосов
/ 21 июля 2010

Следующее, вероятно, делает то, что вам нужно. Обратите внимание на дополнительные <xsl:apply-templates select="@*" /> для копирования атрибутов.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
    xmlns:user="urn:my-scripts">

  <xsl:output method="xml" indent="yes"/>
  <msxsl:script language="C#" implements-prefix="user">
    <![CDATA[
     public string UpperCase(string value){
      return value.ToUpper();
     } ]]>
  </msxsl:script>

  <xsl:param name="dvIndex" select="0" />

  <xsl:template match="DM" >
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:choose>
        <xsl:when test="$dvIndex > 0">
          <xsl:apply-templates select="DV[$dvIndex]"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:apply-templates select="DV"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:copy>
  </xsl:template>

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

  <!--[starts-with(translate(substring(.,1,4),'SQL:','sql:'),'sql:')]-->
  <xsl:template match="@*[user:UpperCase(substring(.,1,4))='SQL:']">
    <xsl:attribute name="{name()}">
      <xsl:value-of select="'parsedSQL'"/>
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>
...