Как отформатировать неизвестные элементы XML определенного класса с помощью XSLT в HTML? - PullRequest
0 голосов
/ 27 мая 2011

Итак, у меня есть XML-документ, сгенерированный моим приложением, например:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE AddressBook>
<?xml-stylesheet type="text/xsl" href="stylesheet.xsl"?>
<AddressBook>
 <Item>
  <UserGeneratedElementName1 class="info">Whatever blah blah</UserGeneratedElementName1>
  <UserGeneratedElementName2 class="info">Whatever blah blah</UserGeneratedElementName2>
 </Item>
 <Item>
  <UserGeneratedElementName3 class="info">Whatever blah blah</UserGeneratedElementName3>
 </Item>
 ...
 ...
 Other Items with user-generated elements with user-generated content...
</AddressBook>

И я хочу превратить его в документ HTML, подобный следующему:

<html>
<head>
 <title>AddressBook</title>
</head>
<body>
 <div class="root">
  <div class="item">
   <b>UserGeneratedElementName1:</b> Whatever blah blah
   <b>UserGeneratedElementName2:</b> Whatever blah blah
  </div>
  <div class="item">
   <b>UserGeneratedElementName3:</b> Whatever blah blah
  </div>
  ...
  ...
  Other transformed items...
 </div>
</body>
</html>

У меня естьпытался понять синтаксис XSLT, но все руководства были либо слишком расплывчаты, чтобы помочь мне с этим, либо слишком глубокими.Также синтаксис XSLT кажется довольно запутанным.Заранее спасибо.

Ответы [ 2 ]

1 голос
/ 27 мая 2011

Посмотрите на этот вопрос здесь

Существует ли элемент имени XSLT?

Вы можете использовать

<xsl:value-of select ="name(.)"/>

или

<xsl:value-of select ="local-name()"/>

для получения имени узла, в зависимости от того, хотите ли вы включить полное префиксное имя или только локальную часть.

Вы должны быть в состоянии собрать их вместе с блоками xsl: for-each, чтобы перебрать первые 3 уровня элементов и сгенерировать искомый HTML.

Примерно так будет работать для фиксированного количества уровней.

    <xsl:for-each select="*">
        <html>
            <head>
                <title><xsl:value-of select="local-name()" /></title>
            </head>
            <body>
                <div class="root">
                    <xsl:for-each select="*">
                        <div>
                            <xsl:attribute name="class">
                                <xsl:value-of select="local-name()" />
                            </xsl:attribute>
                            <xsl:for-each select="*">
                                <b><xsl:value-of select="local-name()" />:</b> <xsl:value-of select="." />
                            </xsl:for-each>
                        </div>
                    </xsl:for-each>
                </div>
            </body>
        </html>
    </xsl:for-each>

Более общий подход будет выглядеть примерно так:

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0">

<xsl:output method="html" indent="yes" version="4.0"/>
<xsl:template match="/">
    <xsl:for-each select="*">
        <html>
            <head>
                <title><xsl:value-of select="local-name()" /></title>
            </head>
            <body>
                <div class="root">
                        <xsl:call-template name="recurseElement">
                            <xsl:with-param name="element" select="." />
                        </xsl:call-template>
                </div>
            </body>
        </html>
    </xsl:for-each>
</xsl:template>
<xsl:template name="recurseElement">
    <xsl:param name="element" />
    <xsl:for-each select="$element/*">
        <xsl:choose>
                <xsl:when test="count(child::*)>0">
                    <div>
                        <xsl:attribute name="class">
                            <xsl:value-of select="local-name()" />
                        </xsl:attribute>
                        <xsl:call-template name="recurseElement">
                            <xsl:with-param name="element" select="." />
                        </xsl:call-template>
                    </div>
                </xsl:when>
                <xsl:otherwise>
                    <b><xsl:value-of select="local-name()" />:</b> <xsl:value-of select="." />
                </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>
</xsl:stylesheet>
0 голосов
/ 28 мая 2011

Это полное XSLT-преобразование :

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

 <xsl:template match="AddressBook">
  <html>
    <head>
     <title>AddressBook</title>
    </head>
    <body>
      <div class="root">
       <xsl:apply-templates/>
      </div>
    </body>
  </html>
 </xsl:template>

 <xsl:template match="Item">
  <div class="item"><xsl:apply-templates/></div>
 </xsl:template>

 <xsl:template match="Item/*">
  <b><xsl:value-of select="name()"/>:</b> <xsl:text/>
  <xsl:value-of select="concat(.,'&#xA;            ')"/>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<AddressBook>
    <Item>
        <UserGeneratedElementName1 class="info">Whatever blah blah</UserGeneratedElementName1>
        <UserGeneratedElementName2 class="info">Whatever blah blah</UserGeneratedElementName2>
    </Item>
    <Item>
        <UserGeneratedElementName3 class="info">Whatever blah blah</UserGeneratedElementName3>
    </Item> ... ... Other Items with user-generated elements with user-generated content...
</AddressBook>

дает желаемый, правильный результат :

<html>
   <head>
      <title>AddressBook</title>
   </head>
   <body>
      <div class="root">
         <div class="item">
            <b>UserGeneratedElementName1:</b>Whatever blah blah
            <b>UserGeneratedElementName2:</b>Whatever blah blah
            </div>
         <div class="item">
            <b>UserGeneratedElementName3:</b>Whatever blah blah
            </div> ... ... Other Items with user-generated elements with user-generated content...
</div>
   </body>
</html>

Объяснение

  1. Шаблоны, соответствующие любому элементу Item и любому дочернему элементу элемента Item.

  2. Использование стандартной функции XPath name() .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...