Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml 在XSLT中编写xsl:value的正确方法_Xml_Visual Studio 2010_Xslt_Xpath - Fatal编程技术网

Xml 在XSLT中编写xsl:value的正确方法

Xml 在XSLT中编写xsl:value的正确方法,xml,visual-studio-2010,xslt,xpath,Xml,Visual Studio 2010,Xslt,Xpath,我正在尝试编写XSLT来将XML从一种格式转换为另一种格式。当我在VS2010中将.xslt文件应用于XML文件时,输出XML结构的创建没有任何问题。但它不填充处理xsl:value of所需的数据 当我使用XMLSpy并计算XPath表达式时,对于下面XSLT中的表达式,它会显示no result。但是当我在XPath表达式的末尾使用node()函数时,它会显示值 编写XPath的正确方法是什么 node()和text()这样的函数每次读取元素内容(当它没有子元素时)真的需要吗?如果不是,为什

我正在尝试编写XSLT来将XML从一种格式转换为另一种格式。当我在VS2010中将
.xslt
文件应用于XML文件时,输出XML结构的创建没有任何问题。但它不填充处理
xsl:value of
所需的数据

当我使用
XMLSpy
并计算
XPath
表达式时,对于下面XSLT中的表达式,它会显示
no result
。但是当我在XPath表达式的末尾使用
node()
函数时,它会显示值

  • 编写XPath的正确方法是什么
  • node()
    text()
    这样的函数每次读取元素内容(当它没有子元素时)真的需要吗?如果不是,为什么XmlSpy也不给出没有这些函数的结果
  • 有时(当我将模板匹配值从“/”更改为“ServiceMessage”)在调试XSLT时,VS 2010会将步骤转换为内置模板规则。为什么会这样?如何在VS 2010中删除内置模板
  • 我从一开始就遵循了。我是XSLT新手

    这是我的XML,我想将其转换为其他XML格式

    <ServiceMessage xmlns="http://requestservice/requests" xmlns:req="http://requestservice/requests/xmlstds">
    
    <TypeOfReq> General </TypeOfReq>
    <Details>
       <Id> 123456789 </Id>
       <SenderDetails>
            <Sender id="345"></Sender>
       </SenderDetails>
    </Details>
    
    </ServiceMessage>
    
    
    一般的
    123456789
    
    这是我的XSLT

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
      <xsl:output method="xml" indent="yes"/>
      <xsl:template match="/">
        <request>
          <requestType>
            <xsl:value-of select="ServiceMessage/TypeOfReq" />
          </requestType>
          <Id>
            <xsl:value-of select="ServiceMessage/Details/Id"/>
          </Id>
          <senderId>
            <xsl:value-of select="ServiceMessage/Details/SenderDetails/Sender/@id"/>
          </senderId>
        </request>
    
      </xsl:template>
    
    
    
    </xsl:stylesheet>
    

    您已经从语法的角度正确编写了xpath。您实际遇到的问题实际上与名称空间有关。在XML中指定了默认名称空间

    <ServiceMessage xmlns="http://requestservice/requests">
    
    
    
    这意味着所有子元素(除非另有规定)都属于该名称空间。但是,在XSLT中,根本没有对该名称空间的引用,因此XSLT正在查找未指定名称空间的元素。您的XML并非如此

    对于XSLT 1.0,需要声明名称空间,如下所示:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="http://requestservice/requests"> 
    
    
    
    然后,您将显式地声明用于匹配元素的位置

    <xsl:value-of select="s:ServiceMessage/s:TypeOfReq" />
    
    
    
    这是完整的XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="http://requestservice/requests">
       <xsl:output method="xml" indent="yes"/>
       <xsl:template match="/">
          <request>
             <requestType>
                <xsl:value-of select="s:ServiceMessage/s:TypeOfReq"/>
             </requestType>
             <Id>
                <xsl:value-of select="s:ServiceMessage/s:Details/s:Id"/>
             </Id>
             <senderId>
                <xsl:value-of select="s:ServiceMessage/s:Details/s:SenderDetails/s:Sender/@id"/>
             </senderId>
          </request>
       </xsl:template>
    </xsl:stylesheet>
    
    
    
    应用于XML时,将输出以下内容

    <request xmlns:s="http://requestservice/requests">
       <requestType> General </requestType>
       <Id> 123456789 </Id>
       <senderId>345</senderId>
    </request>
    
    
    一般的
    123456789
    345
    

    请注意,此处字母“s”的选择完全是任意的,它可能是任何东西。

    要回答您的第三个问题“如何摆脱内置模板?”

    如果没有为xml中出现的元素指定模板,那么VS将应用标识模板,该模板只会将源元素复制到输出中

    <xsl:template match="/ | @* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    
    
    
    有关详细信息,请参阅

    (我不知道是否可以关闭它,因为我这里只有VS Express,它不提供Xslt调试)

    作为一般规则,您应该始终为要处理的所有元素指定模板,因此您的基本xslt将始终从

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:s="http://requestservice/requests">
    
        <xsl:template match="/">
            <xsl:apply-templates />
        </xsl:template>
    
    </xsl:stylesheet>
    
    
    
    接下来,在您的示例中,为根元素ServiceMessage添加一个模板

    
    
    谢谢@Filburt。更正错别字。太棒了!成功了。我接受它作为回答。但您是否知道,为什么XmlSpy不提供没有
    node()
    text()函数的结果?为什么它在没有表达式中指定的名称空间的情况下正确计算Xpath表达式(在本例中我使用node())呢?node()将匹配元素、文本、注释和处理指令,而text()只匹配text()。通常不会将text()与xsl:value一起使用,因为此函数无论如何都会返回节点的文本。注意(在XSLT1.0中)如果执行xsl:value of,并且xpath表达式匹配多个节点,它将只返回它匹配的第一个节点的文本。接受此作为答案,因为它已经准确地识别了问题并提供了解决方案。关于VS内置模板的其他问题由@Filburt.Thank@Filburt回答。它帮助我理解了我在VS 2010调试过程中遇到的问题。>>如果您没有为xml中出现的元素指定模板,VS将应用标识模板,该模板将简单地将源元素复制到您的输出中。@torazaburo如果您更了解,请告诉我们-否则我的答案包含(缩短和简化)版本的默认规则不复制源元素。它只对其子元素执行
    。如果不是这样,就没有理由复制我们在解决此类问题时经常看到的样板文件(“复制XML,但在此过程中执行此小转换…”)。默认规则复制到输出的唯一内容是文本节点。您所指的MS页面并不是说默认规则复制节点,而是说它处理节点。
    <xsl:template match="s:ServiceMessage">
        <!-- usually apply-templates, in your case create new output element(s) -->
    <xsl:template>