2011-12-21 3 views
1

Это была бы моя первая попытка написать XSLT, который фактически что-то значил, и это помогает мне в моей работе. Я уже написал xpath xpression и добрался с ними очень хорошо, просто нужно, чтобы мои ноги были мокрыми с помощью XSLT, чтобы действительно начать готовить. Anywho,Написание XSLT для вытягивания определенных атрибутов из файла XML

У меня есть XML-файл с определенными узлами в нем с атрибутами value. Я хочу, чтобы все узлы с name атрибуты, чтобы распечатать их value атрибуты в текстовом файле ...

Вот то, что я до сих пор ... Пример XML

<?xml version="1.0"?> 
<dataTemplateSpecification> 
<templates> 
<template> 
    <elements> 
    <element id="element0" name="PatientId" display="Patient ID" dataType="String" visable="true" readOnly="false" value="207"> 
     <mapping path="//Template/TemplateData/ACOData/PATIENT_ID" /> 
     <validation> 
     <rules> 
      <rule id="r0" test="#element0.value == ''"> 
      <fail> 
       <html> 
       <b>Patient ID is null, value must be present</b> 
       </html> 
      </fail> 
      </rule> 
     </rules> 
     </validation> 
    </element> 
    <element id="element1" name="EncounterId" display="Encounter ID" dataType="String" visable="true" readOnly="false" value="144"> 
     <mapping path="//Template/TemplateData/ACOData/FOCUSED_READMISSIONS_ID" /> 
     <validation> 
     <rules> 
      <rule id="r0" test="#element0.value == ''"> 
      <fail> 
       <html> 
       <b>Patient ID is null, value must be present</b> 
       </html> 
      </fail> 
      </rule> 
     </rules> 
     </validation> 
    </element> 
    </template></template></dataTemplateSpecification> 

Вот очень простой XSLT, что я написал ...

<?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"> 
<xsl:output method="text" indent="yes"/> 

<xsl:template match="//dataTemplateSpecification/templates/template/elements/element[@name=*]"> 
    <xsl:copy> 
     <xsl:apply-templates select="@value"/> 
    </xsl:copy> 
</xsl:template> 

Я буду держать растрескивания на это, и если вы, ребята, могли бы помочь на всех, я бы вечно gratefu л. Я, конечно, опубликую решение для любого, кто читает это, а также заинтригован этим вопросом, должен ли я найти решение самостоятельно. Спасибо.

ответ

2

Здесь, вероятно, один из самых простых и кратчайшим полных преобразований, которые выполняет требуемую обработку:

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

<xsl:template match="element[@name and @value]"> 
    <element> 
     <xsl:value-of select= 
     "concat(@name, ': ', @value)"/> 
    </element> 
</xsl:template> 
<xsl:template match="text()"/> 
</xsl:stylesheet> 

Когда это преобразование применяется на прилагаемом XML (исправлено несколько раз, чтобы быть сделаны wellformed) :

<dataTemplateSpecification> 
    <templates> 
     <template> 
      <elements> 
       <element id="element0" name="PatientId" display="Patient ID" dataType="String" visable="true" readOnly="false" value="207"> 
        <mapping path="//Template/TemplateData/ACOData/PATIENT_ID" /> 
        <validation> 
         <rules> 
          <rule id="r0" test="#element0.value == ''"> 
           <fail> 
            <html> 
             <b>Patient ID is null, value must be present</b> 
            </html> 
           </fail> 
          </rule> 
         </rules> 
        </validation> 
       </element> 
       <element id="element1" name="EncounterId" display="Encounter ID" dataType="String" visable="true" readOnly="false" value="144"> 
        <mapping path="//Template/TemplateData/ACOData/FOCUSED_READMISSIONS_ID" /> 
        <validation> 
         <rules> 
          <rule id="r0" test="#element0.value == ''"> 
           <fail> 
            <html> 
             <b>Patient ID is null, value must be present</b> 
            </html> 
           </fail> 
          </rule> 
         </rules> 
        </validation> 
       </element> 
      </elements> 
     </template> 
    </templates> 
</dataTemplateSpecification> 

разыскиваемый, правильный результат получается:

<element>PatientId: 207</element> 
<element>EncounterId: 144</element> 
1

Ваш предикат XPath не делает то, что, по вашему мнению, он делает. * - это селектор для всех дочерних элементов, а не шаблон шаблона строки. Я предполагаю, что вы скорее хотите что-то подобное (все element элементов, которые имеют как name и атрибут value):

//element[@name and @value] 

И для распечатки значений атрибутов, вы можете захотеть взглянуть на xsl:value-of вместо xsl:copy и xsl:apply-templates, если вы не хотите на самом деле скопировать элемент.

1

Нечто подобное возможно:

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

<xsl:output method="text"/> 

<xsl:variable name='newline'><xsl:text> 
</xsl:text></xsl:variable> 

<xsl:template match="//elements"> 
    <xsl:for-each select="//element[@name]"> 
    <xsl:value-of select="concat(@value,$newline)"/> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 
0

На самом деле это было не так уж плохо. Для первого XSLT я не мог просить намного проще. то, что я написал ранее, почти сработало бы. Но для этого я должен был бы написать

<?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"> 
<xsl:output method="text" indent="yes"/> 

<xsl:template match="//dataTemplateSpecification/templates/template/elements/element"> 
    <xsl:copy> 
     <xsl:value-of select="@name"></xsl:value-of>: <xsl:value-of select="@value"/> 
    </xsl:copy> 
</xsl:template> 

Это, казалось, работали достаточно хорошо.

+1

DMainEvent: Не так уж плохо для начала. Вот несколько замечаний: 1. Всегда используйте краткую форму ''. Write: '' и * not * ''.2: шаблон соответствия шаблону указывает выражение * relative * XPath (очень редко состоящее из нескольких шагов местоположения). В вашем случае это может быть просто: '' 3. Вы можете использовать одно выражение XPath (и, таким образом, одно значение ''), чтобы указать конкатенацию более чем одна строка: просто используйте функцию 'concat()'. –

Смежные вопросы