gpt4 book ai didi

c# - XSL 转换 XML->XML 仅输出文本?

转载 作者:太空宇宙 更新时间:2023-11-03 22:27:23 24 4
gpt4 key购买 nike

您好,我有以下 XAML 代码,它是 XamlWriter.Save() 的输出:

<StackPanel Name="itemStack" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:mm="clr-namespace:MindManager;assembly=MindManager">
<mm:Item Width="Auto" Height="Auto">
<Border BorderThickness="10,10,10,10" Name="border1" Height="Auto">
<DockPanel>
<DockPanel LastChildFill="True" Name="dockPanel1" Height="33" DockPanel.Dock="Top">
<Button Name="deleteItemButton" Width="26" Height="21.638" FlowDirection="LeftToRight" DockPanel.Dock="Right" Grid.IsSharedSizeScope="False">x</Button>
<TextBox Name="tagsTextBox" Height="19">1</TextBox>
</DockPanel>
<TextBox TextWrapping="Wrap" MinLines="5" AcceptsReturn="True" AcceptsTab="True" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled" AutoWordSelection="True" Name="contentTextBox" Width="Auto" MinWidth="600" Height="Auto" MinHeight="80">2</TextBox>
</DockPanel>
</Border>
</mm:Item>
<mm:Item Width="Auto" Height="Auto">
<Border BorderThickness="10,10,10,10" Name="border1" Height="Auto">
<DockPanel>
<DockPanel LastChildFill="True" Name="dockPanel1" Height="33" DockPanel.Dock="Top">
<Button Name="deleteItemButton" Width="26" Height="21.638" FlowDirection="LeftToRight" DockPanel.Dock="Right" Grid.IsSharedSizeScope="False">x</Button>
<TextBox Name="tagsTextBox" Height="19">3</TextBox>
</DockPanel>
<TextBox TextWrapping="Wrap" MinLines="5" AcceptsReturn="True" AcceptsTab="True" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled" AutoWordSelection="True" Name="contentTextBox" Width="Auto" MinWidth="600" Height="Auto" MinHeight="80">4</TextBox>
</DockPanel>
</Border>
</mm:Item>
</StackPanel>

我想使用以下 XSL 将其转换为更简单的 XML:

<?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" xmlns:mm="clr-namespace:MindManager;assembly=MindManager">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/StackPanel">
<mindcontainer>
<xsl:for-each select="mm:Item">
<minditem>
<xsl:value-of select="/tagsTextBox"/>
<xsl:value-of select="/contentTextBox"/>
</minditem>
</xsl:for-each>
</mindcontainer>
</xsl:template>
</xsl:stylesheet>

我希望输出具有以下格式:

<mindcontainer>
<minditem>
content of tagsTextBox
content of contentTextBox
</minditem>
<minditem>
content of tagsTextBox
content of contentTextBox
</minditem>
</mindcontainer>

但问题是我从中得到的是:

  x
1

2







x
3

4

可以看到只有文本,没有文本,过滤器也不起作用 x 是我不想输出的关闭按钮的标签。

这是我用来执行转换的代码:

    XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent=true;

StringBuilder sb = new StringBuilder();
using (XmlWriter wr = XmlWriter.Create(sb, settings))
{
XamlWriter.Save(scrollViewer1.Content, wr);
}

settings.ConformanceLevel = ConformanceLevel.Auto;
using (XmlReader rd = XmlReader.Create(new StringReader(sb.ToString())))
{
XslCompiledTransform trans = new XslCompiledTransform();
trans.Load("output.xsl");

trans.Transform(rd, XmlWriter.Create("mindstore.xms", settings));
}

最佳答案

在 XPath/XSLT 1.0 中,要选择(或匹配) namespace 中的元素,您必须声明 namespace 前缀并在表达式(或模式)中使用该前缀。不要被 <StackPanel> 的事实所迷惑其他元素不在输入 XML 中使用前缀。它使用默认命名空间,由默认命名空间声明确定:

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

因此您需要在样式表中进行相应的声明(就像您对“mm”命名空间所做的那样),除了您需要选择要使用的命名空间前缀。任何前缀都可以(就像您实际上不必使用“mm”一样)。

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
...>

然后,在您的样式表中,您需要更新表达式和模式以使用您选择的前缀(在我上面的示例中为“x”):

<xsl:template match="/x:StackPanel">

您看到您得到的输出的原因是您的模板规则从未被调用(因为名称不匹配)。相反,将调用每个 XPath 节点类型的内置模板规则。对于根节点和元素节点,就是一直处理children。对于文本节点,就是将它们复制过来。因此,您看到的行为与任何空样式表(没有模板规则)所获得的行为相同:输入文档中所有文本节点的转储。

必须在每个表达式或模式中为每个名称测试添加前缀可能会很痛苦。这就是为什么 XSLT 2.0 引入了一个名为 xpath-default-namespace 的特性。 ,这使得 XPath 表达式和 XSLT 模式可以使用默认命名空间,就像 XML 中的元素一样。在这种情况下,您所要做的就是添加一行:

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
...>

但这只是在您使用 XSLT 2.0 处理器的情况下。 (例如,MSXML 不支持 XSLT 2.0。)

在我离开你之前,我在你的样式表中发现了更多问题(毫无疑问,你接下来会发现):

        <xsl:value-of select="/tagsTextBox"/>
<xsl:value-of select="/contentTextBox"/>

以“/”开头的表达式表示“从文档/根节点开始”。所以这些表达式正在寻找 <tagsTextBox>文档元素和 <contentTextBox>文档元素,分别。根据我在您的示例输入文档中看到的内容,我认为您的意思是这样写的:

        <xsl:value-of select=".//x:TextBox[@Name = 'tagsTextBox']"/>
<xsl:value-of select=".//x:TextBox[@Name = 'contentTextBox']"/>

希望对您有所帮助!让我知道是否需要进一步解释。

关于c# - XSL 转换 XML->XML 仅输出文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/845104/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com