编写XSLT以从XML文件中提取某些属性

时间:2011-12-21 15:08:33

标签: xml xslt-2.0

这是我编写XSLT的第一次尝试,它实际上做了一些重要的事情,这对我的工作有所帮助。我以前写过xpath xpression,并且已经很好用了它们,只需要用XSLT弄湿我的脚就可以开始做饭了。 Anywho,

我有一个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>

我会继续坚持这个,如果你们能帮助我,我会永远感激。我当然会为任何阅读此内容的人发布解决方案,如果我自己发现解决方案,我也会对这个问题感兴趣。谢谢。

4 个答案:

答案 0 :(得分: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 应用此转换时(已多次更正以使其格式正确):

<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 :(得分:1)

您的XPath谓词没有按照您的想法执行。 *是所有子元素的选择器,而不是字符串通配符模式。我假设您更喜欢类似的内容(所有element元素同时包含namevalue属性:

//element[@name and @value]

要打印出属性值,您可能需要查看xsl:value-of而不是xsl:copyxsl:apply-templates,除非您想要实际复制元素。

答案 2 :(得分: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>

答案 3 :(得分: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>

这似乎工作得很好。