简体   繁体   English

如何将Xpath语法转换为XSL / XSLT语法?

[英]How to convert Xpath syntax to XSL/XSLT syntax?

I understand how XPath syntax works, and can write Xpath commands to extract certain information from a XML file. 我了解XPath语法的工作原理,并且可以编写Xpath命令以从XML文件提取某些信息。
I would like to convert my XPath commands to XSLT scripts so that someone else can just run the script over the XML file to get the same output. 我想将XPath命令转换为XSLT脚本,以便其他人可以在XML文件上运行该脚本以获取相同的输出。

eg 例如

I have a XML file that, let's say, looks like follows: 我有一个XML文件,例如,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
  <library>
        <section id="109196796">
            <master_information>
                <shelf_identifier>
                    <identifier type="CodeX" type_id="2">LB1500605917</identifier>
                    <identifier type="Common Code" type_id="15">150060591</identifier>
                </shelf_identifier>
                <shelf_master>
                    <section_type>1</section_type>
                    <book_type>3</book_type>
                </shelf_master>
            </master_information>
        </section>
        <section id="109196798">
            <master_information>
                <shelf_identifier>
                    <identifier type="CodeX" type_id="2">LB0777775917</identifier>
                    <identifier type="Common Code" type_id="15">077777591</identifier>
                </shelf_identifier>
                <shelf_master>
                    <section_type>1</section_type>
                    <book_type>3</book_type>
                </shelf_master>
            </master_information>
        </section>
        <section id="109196800">
            <master_information>
                <shelf_identifier>
                    <identifier type="CodeX" type_id="2">LB2589165917</identifier>
                    <identifier type="Common Code" type_id="15">258916591</identifier>
                </shelf_identifier>
                <shelf_master>
                    <section_type>1</section_type>
                    <book_type>3</book_type>
                </shelf_master>
            </master_information>
        </section>
  </library>


If I run the XPath command below, 如果我运行下面的XPath命令,

//identifier[@type='CodeX']

I get the output: 我得到的输出:

LB1500605917
LB0777775917
LB2589165917

..which is expected. ..这是预期的。 Now, I tried converting the XPath command to an XSL syntax as below: 现在,我尝试将XPath命令转换为XSL语法,如下所示:

<?xml version="1.0" encoding="ISO-8859-1"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:variable name="return">
    <xsl:text>
</xsl:text> <!-- defined a line break -->
    </xsl:variable>
    <xsl:template match="//library"></xsl:template>
    <xsl:template match="//section/master_information/shelf_identifier/identifier"> 
        <xsl:value-of select="@type='CodeX'"/>
        <xsl:value-of select="$return"/> <!-- this basically puts a line break -->
    </xsl:template>
</xsl:stylesheet>

The XSL seems to be correct. XSL似乎是正确的。 However, no output is generated. 但是,不会生成任何输出。

I am new to XSL/XSLT. 我是XSL / XSLT的新手。 What am I doing wrong? 我究竟做错了什么?

What you could do is add a template matching the same nodes as your xpath, then outputting the value along with a newline... 您可以做的是添加一个与xpath匹配相同节点的模板,然后输出值和换行符...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <!--The strip-space isn't completely necessary. I just always include it in my
  default stylesheets. It strips whitespace. You can preserve whitespace with
  xsl:preserve-space. See https://www.w3.org/TR/xslt#strip for more details.-->
  <xsl:strip-space elements="*"/>

  <!--Suppress output of text nodes by built-in templates.-->
  <xsl:template match="text()"/>

  <!--Match "indentifier" elements that contain a "type" attribute
  with the value of "CodeX".-->
  <xsl:template match="identifier[@type='CodeX']">
    <!--Output the value of the current context ("identifier") concatenated with
    a newline. ("&#xA;" is a hex entity reference. You could also use a decimal
    reference ("&#10;")). You could use either of these references as the value
    of a variable too (or even declare it as an entity).
    I use normalize-space() instead of . to clean up any additional spaces.
    See https://www.w3.org/TR/xpath/#function-normalize-space for details.-->
    <xsl:value-of select="concat(normalize-space(),'&#xA;')"/>
  </xsl:template>

</xsl:stylesheet>

Notice the empty template that matches text() . 注意匹配text()的空模板。 This is added to suppress the output of text() nodes by XSLT's built-in template rules . 通过XSLT的内置模板规则添加了此功能以抑制text()节点的输出。

Also note that I didn't use // in my match. 另请注意,我没有在比赛中使用// This is also because of the built-in rules; 这也是由于内置规则; they allow recursive processing by default. 它们默认允许递归处理。

Why don't you do simply: 为什么不简单地做:

XSLT 1.0 XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>

<xsl:template match="/">
    <xsl:for-each select="//identifier[@type='CodeX']">
        <xsl:value-of select="."/>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM