У меня есть входной XML ниже и я хочу, чтобы он преобразовался в другой выходной XML с помощью XSLT.

Мой входной XML-код выглядит следующим образом:

<?xml version="1.0" encoding="utf-8"?>
<AppSettings>
 <Plugins>
  <AssemblyName>Version=5.0, Culture=neutral, PublicKeyToken=null</AssemblyName>
  <TypeName>AAA</TypeName>
   <Version>?</Version>
   <Configuration>
    <AppData xmlns="http://tempuri.org/AppData.xsd">
     <Readers>
      <Id>1</Id>
      <Port>2500</Port>
      <Type>M100</Type>
     </Readers>
     </AppData>
    </Configuration>
   </Plugins>
  <Plugins>
  <AssemblyName>Version=5.0, Culture=neutral, PublicKeyToken=null</AssemblyName>
 <TypeName>BBB</TypeName>
 <Version>?</Version>
 <Configuration>
  <AppData xmlns="http://tempuri.org/AppData.xsd">
    <Readers>
      <Id>2</Id>
      <Port>3500</Port>
      <Type>M200</Type>
    </Readers>
  </AppData>
  </Configuration>
 </Plugins>
</AppSettings>

Сверху XML я хочу выбрать узел «Plugins», имеющий TypeName «BBB», и использовать его дочерние узлы, чтобы получить результат ниже.

<?xml version="1.0" encoding="utf-8"?>
 <AppSettings>
  <Inputs>
   <PlugInType>M200</PlugInType>
   <Port>3500</Port>
   </Inputs>
  </AppSettings>

Я пробовал использовать ниже XSLT, но не получил требуемого вывода

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
 <xsl:output method="xml" indent="yes"/>
 <xsl:template match="/">
  <AppSettings>
  <Inputs>
    <xsl:for-each select="AppSettings">
      <xsl:for-each select="//Plugins[TypeName=BBB]">
        <xsl:for-each select="Configuration/AppData/Readers">
          <PlugInType>
            <xsl:value-of select="Type"/>
          </PlugInType>
          <Port>
            <xsl:value-of select="Port"/>
          </Port>
        </xsl:for-each>
      </xsl:for-each>
    </xsl:for-each>
  </Inputs>
  </AppSettings>
 </xsl:template>

Дай мне знать, где я ошибаюсь

0
rajcool111 30 Апр 2014 в 17:42

2 ответа

Лучший ответ

С вашей таблицей стилей есть две основные проблемы (и множество второстепенных). Две основные проблемы:

<xsl:for-each select="//Plugins[TypeName=BBB]">

Должно быть:

<xsl:for-each select="//Plugins[TypeName='BBB']">

И тот факт, что вы игнорируете пространство имен, объявленное для элемента AppData и его потомков.

Кроме этого, я не думаю, что вам нужно так много операторов xsl:for-each. Попробуйте просто:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ad="http://tempuri.org/AppData.xsd"
exclude-result-prefixes="ad">

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

<xsl:template match="/">
    <AppSettings>
        <Inputs>
            <xsl:for-each select="AppSettings/Plugins[TypeName='BBB']">
                <PlugInType>
                    <xsl:value-of select="Configuration/ad:AppData/ad:Readers/ad:Type"/>
                </PlugInType>
                <Port>
                    <xsl:value-of select="Configuration/ad:AppData/ad:Readers/ad:Port"/>
                </Port>
            </xsl:for-each>
        </Inputs>
    </AppSettings>
</xsl:template>

</xsl:stylesheet>

Дополнение:

Я хочу повторить этот xml дальше. Я хочу выбрать узел «Плагины» с именем типа «BBB» и считывающими устройствами с портом «3500».

Просто добавьте еще один предикат к выражению выбора:

<xsl:for-each select="AppSettings/Plugins[TypeName='BBB'][Configuration/ad:AppData/ad:Readers/ad:Port='3500']">
0
michael.hor257k 30 Апр 2014 в 17:11

Я думаю ты хочешь

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
  xmlns:df="http://tempuri.org/AppData.xsd" exclude-result-prefixes="df">
 <xsl:output method="xml" indent="yes"/>
 <xsl:template match="/">
  <AppSettings>
  <Inputs>
    <xsl:for-each select="AppSettings//Plugins[TypeName='BBB']/Configuration/df:AppData/df:Readers">
          <PlugInType>
            <xsl:value-of select="df:Type"/>
          </PlugInType>
          <Port>
            <xsl:value-of select="df:Port"/>
          </Port>
    </xsl:for-each>
  </Inputs>
  </AppSettings>
 </xsl:template>

Позаботиться о xmlns="http://tempuri.org/AppData.xsd" в XML.

0
Martin Honnen 30 Апр 2014 в 16:28